1. 为什么选择PWM+DMA驱动WS2812B
第一次用STM32点WS2812B彩灯的时候,我直接用了GPIO模拟时序的方法。结果灯珠一会儿亮一会儿灭,颜色还经常乱跳。后来用示波器一看,发现是中断打断了延时函数,导致时序完全错乱。那时候我才明白,WS2812B对时序的要求有多么苛刻——高低电平的时间误差不能超过150纳秒!
于是我开始研究PWM+DMA的方案,这个方案彻底解决了时序稳定性问题。简单来说,就是用硬件定时器产生精确的PWM波形,再用DMA自动传输数据,完全不需要CPU参与。实测下来,驱动100个灯珠和驱动2个灯珠的CPU占用率几乎一样,而且颜色显示非常稳定,再也不会出现随机闪烁的问题。
WS2812B每个灯珠需要24位数据(GRB格式),每个位用不同的脉冲宽度表示0和1。传统的GPIO模拟方式需要CPU精确控制每个高低电平的持续时间,任何中断都会导致时序错乱。而PWM+DMA方案中,硬件定时器会自动生成精确的波形,DMA则负责将内存中的数据传输到定时器,整个过程完全由硬件完成。
2. 硬件连接与电源设计
2.1 信号线连接
WS2812B的接线看起来简单,但实际上有很多坑。我最初用3.3V直接驱动数据线,结果灯珠经常不亮或者颜色异常。后来才发现,WS2812B需要5V电平的信号输入,而STM32的GPIO输出是3.3V电平。
解决方案有两种:一是使用电平转换芯片,如74HCT245;二是简单的电阻分压方案。如果灯珠数量不多,我推荐用电阻分压,成本低且效果不错。具体接法是:STM32的PWM输出引脚串联一个100欧姆电阻后,再并联一个100欧姆电阻到地,从中间节点引出信号到WS2812B的DIN引脚。
// STM32引脚配置示例(以TIM4_CH3为例)
// GPIO: PB8
// 模式: Alternate Function Push Pull
// 速度: High
// 上拉/下拉: No pull-up/pull-down
2.2 电源设计与滤波
电源是另一个容易出问题的地方。WS2812B在全白亮度时,每个灯珠可能消耗60mA电流。如果你驱动30个灯珠,总电流就达到1.8A!这么高的电流下,电源线的压降和噪声都会成为问题。
我的经验是:每30个灯珠增加一个5V电源注入点,使用至少20AWG的电源线。在每个灯带的首端,并联一个100μF的电解电容和一个0.1μF的陶瓷电容,前者滤除低频噪声,后者滤除高频噪声。
如果灯珠数量较多,建议使用独立的5V电源为灯带供电,同时确保STM32和WS2812B的GND连接在一起。我曾经因为忘记共地,调试了整整一个下午才发现问题。
3. CubeMX配置详解
3.1 时钟树配置
时钟配置是PWM时序精度的基础。以STM32F103C8T6为例,我们需要确保定时器时钟为72MHz,这样每个计数周期就是13.89纳秒,能够精确控制WS2812B所需的时序。
在CubeMX中,首先配置HSE为8MHz,PLL倍频9倍得到72MHz系统时钟。APB1预分频器设


410

被折叠的 条评论
为什么被折叠?



