发布时间:2023-07-20 15:00
用STM32控制WS2812 RGB灯带的代码资料不多。这里的代码是通过示波器一点一点调整得到的。本着开源原则,和大家分享学习。
核心代码如下:
// 引脚对应的寄存器(更多信息见下文)
#define A0_HIGH GPIOA->BSRR = 1 // A low electrical level. (GPIO_PIN_0: 1)
#define A0_LOW GPIOA->BSRR = 65536u // A high electrical level.(GPIO_PIN_0: 1 << 16u)
#define A1_HIGH GPIOA->BSRR = 2 // A low electrical level. (GPIO_PIN_1: 2)
#define A1_LOW GPIOA->BSRR = 131072u // A high electrical level.(GPIO_PIN_1: 2 << 16u)
#define B12_HIGH GPIOB->BSRR = 4096 // A low electrical level. (GPIO_PIN_12: 4096)
#define B12_LOW GPIOB->BSRR = 268435456u // A high electrical level.(GPIO_PIN_12: 4096 << 16u)
#define HIGH B12_HIGH // 持续一个很短时间的高电平
#define LOW B12_LOW // 持续一个很短时间的低电平
// 连续多个HIGH/LOW == 一个HIGH/LOW + delay函数 (卡示波器得到的)
#define SIG1() HIGH;HIGH;HIGH; HIGH;HIGH;LOW // 一个 signal 1.
#define SIG0() HIGH;HIGH;LOW; LOW;LOW;LOW // 一个 signal 0.
// 示例颜色 (注意这里的颜色顺序是:高位->低位 —— G->R->B)
#define RED 0x00ff00
#define GREEN 0xff0000
#define BLUE 0x0000ff
#define LED_LEN 144 // 灯带长度
#define BIT_LEN 24 // 每颗灯对应24位 0/1 signal
uint32_t led_buf[LED_LEN] = { 0 }; // 存储每颗灯的颜色值,范围:[0, 0xffffff].
void sync() {
uint32_t bit_buf[LED_LEN * BIT_LEN] = { 0 }; // 将要传输的bit数组
for (uint32_t i = 0; i < LED_LEN; ++i) {
for (uint32_t j = 0; j < BIT_LEN; ++j) {
bit_buf[i * BIT_LEN + j] = (led_buf[i] >> (BIT_LEN - 1 - j)) & 1; // 高位先传
}
}
__disable_irq(); // 关闭中断
for (uint32_t i = 0; i < LED_LEN * BIT_LEN; ++i) {
if (bit_buf[i]) {
SIG1();
} else {
SIG0();
}
}
__enable_irq(); // 开启中断
}
#define GPIO_PIN_0 ((uint16_t)0x0001) /* Pin 0 selected */
#define GPIO_PIN_1 ((uint16_t)0x0002) /* Pin 1 selected */
#define GPIO_PIN_2 ((uint16_t)0x0004) /* Pin 2 selected */
#define GPIO_PIN_3 ((uint16_t)0x0008) /* Pin 3 selected */
#define GPIO_PIN_4 ((uint16_t)0x0010) /* Pin 4 selected */
#define GPIO_PIN_5 ((uint16_t)0x0020) /* Pin 5 selected */
#define GPIO_PIN_6 ((uint16_t)0x0040) /* Pin 6 selected */
#define GPIO_PIN_7 ((uint16_t)0x0080) /* Pin 7 selected */
#define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */
#define GPIO_PIN_9 ((uint16_t)0x0200) /* Pin 9 selected */
#define GPIO_PIN_10 ((uint16_t)0x0400) /* Pin 10 selected */
#define GPIO_PIN_11 ((uint16_t)0x0800) /* Pin 11 selected */
#define GPIO_PIN_12 ((uint16_t)0x1000) /* Pin 12 selected */
#define GPIO_PIN_13 ((uint16_t)0x2000) /* Pin 13 selected */
#define GPIO_PIN_14 ((uint16_t)0x4000) /* Pin 14 selected */
#define GPIO_PIN_15 ((uint16_t)0x8000) /* Pin 15 selected */
#define GPIO_PIN_All ((uint16_t)0xFFFF) /* All pins selected */
GPIOx->BSRR = GPIO_Pin_x; // 高电平
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u; // 低电平
点击下载
WS2812手册
个人经验