本帖最后由 lilijin1995 于 2022-9-17 17:54 编辑
#申请原创# @21小跑堂
---------------------
【WS2812驱动ch582板】基于CH582使用IO模拟时序驱动WS2812,实现红绿蓝切换
1.背景选择IO口驱动WS2812实属无奈,事情是这样的,本来想使用TIM PWM+DMA的方式,但是画板子的时候选择了CH582的第14pin,即PB7 PWM9模式,按理说PWM模式没有DMA问题也不大嘛,但是事情不是这样的,因为这个PWM模式,他的周期只能选择如下几种; - typedef enum
- {
- PWMX_Cycle_256 = 0, // 256 个PWMX周期
- PWMX_Cycle_255, // 255 个PWMX周期
- PWMX_Cycle_128, // 128 个PWMX周期
- PWMX_Cycle_127, // 127 个PWMX周期
- PWMX_Cycle_64, // 64 个PWMX周期
- PWMX_Cycle_63, // 63 个PWMX周期
- PWMX_Cycle_32, // 32 个PWMX周期
- PWMX_Cycle_31, // 31 个PWMX周期
- } PWMX_CycleTypeDef;
并且我们的主频是60M,选择分频系数为1不分频,最后算出来1码没有达到800K,尝试了好几种配置,能点亮红色,绿色,蓝色不亮; 2. WS2812B驱动原理通过阅读规格书,如下图所示,可以知道WS2812B的数据刷新率为800K,
再有时序定义如下:0码由T0H和T0L组成,1码也差不多,RESET码是断帧码,断帧就是第几个灯珠停止,点亮几颗灯的意思;
最后是数据结构,如下,一个灯珠的数据由24bit的GRB组成,N个24bit的GRB点亮N个灯珠,最后Reset断帧,其中1个bit如果是二进制的1,那么时序对应的是1码,反之是0码;
3. 代码实现:这里我们直接上代码,其中Set0Code和Set1Code是基于1码和0码的时序用示波器调出来的,这里就介绍方法不介绍过程了;方法是直接调用SendOneFrame(0xFF);全发1码驱动1码,确定0码是发SendOneFrame(0x00),看高低电平即可;
4.下载验证:可以看到RGB大约1ms切换;
附件是源码
|