本帖最后由 6552918 于 2022-11-29 21:04 编辑
#申请原创# #技术资源#
常用的幻彩LED灯有WS2812B和WS2811等,下面我介绍一下使用RD8T36P驱动WS2812B
先来看一下WS2812B的技术介绍
看以看出,码元周期是1.25us(800K)
WS2812B只需要一个管脚即可进行数据传输。
常见的驱动方式如下
----
| 优点
| 缺点
| 驱动方式
| IO驱动方式
| 控制简单,控制灵活
| 驱动周期容易被打断,容易显示出错
| | SPI查询方式
| 控制较简单
| 占用管脚多,受SPI时钟限制,有时无法达到最大速度
| | SPI中断方式
| 控制较简单,可以尽量不受中断干扰(需配置为最高优先级)
| 占用管脚多,受SPI时钟限制,有时无法达到最大速度
| | SPI+DMA方式
| 不受中断干扰,可以减轻CPU负担
| 控制复杂,占用管脚多,受SPI时钟限制,有时无法达到最大速度
| | PWM查询方式
| 可以灵活配置驱动频率,可以最大速度驱动
| 控制较复杂,容易被中断干扰,容易显示出错
| | PWM中断方式
| 可以灵活配置驱动频率,可以最大速度驱动,可以尽量不受中断干扰(需配置为最高优先级)
| 控制较复杂
| | PWM+DMA方式
| 不受中断干扰,可以最大速度驱动,,可以减轻CPU负担
| 控制复杂
| 由于RD8T36P是8051内核,没有DMA,所以我采用了IO和PWM方式
相关初始化如下:
在PWM初始化中发现一处库函数错误
PWM_PolarityConfig(PWM30,PWM_POLARITY_INVERT);
另外,还有个编程上的问题需要注意一下。
void WS281x_Show(void)实现了各种控制方式的输出啊,相关说明如下
由于PWM3输出和TIM3共用中断,所以在TM3中断中添加先关PWM处理函数
使用GPIO方式驱动,需要将WS281X.h内的PWM_IRQ宏和WS2812_GPIO_Mode宏关闭
使用GPIO驱动WS2812B波形如下
IO控制0码周期
代码和波形对应关系
IO控制1码周期
代码和波形对应关系
低电平维持时间是由代码执行时间决定的,所以低电平后没有加延时
准备使用PWM驱动时,发现如下问题
最高速度800K(周期1.25us)时PWM输出和进入中断处理时间关系
PWM周期为1.25,占空比为50%是PWM管脚输出
周期为1.25时,进中断周期为3us左右
从上述波形来看,在PWM周期为1.25us情况下,进中断的时间需要1.5us多,无法实现在一个PWM周内处理完前一个PWM的中断。也就是无法实现中断方式让PWM在800K频率下驱动WS2812(800K是WS2812的最大速度)
为了实现使用PWM驱动WS2812B,我牺牲驱动速度,将速度降到位200K(5us)
PWM模式1码和0码的占空比对应的时间
PWM中断方式选择
PWM中断方式0码,高电平320ns,高电平4.7us和程序设定基本一致
PWM中断方式1码,高电平620ns,高电平4.4us和程序设定基本一致
PWM查询方式选择
PWM查询模式下0码,高电平320ns,高电平4.7us和程序设定基本一致(与PWM中断方式一致)
PWM查询方式1码,高电平620ns,高电平4.4us和程序设定基本一致与PWM中断方式一致)
至此,实现了GPIO、PWM查询方式和PWM中断这3种方式的WS2182B的驱动,代码理论还支持WS2811,但没有测试。
源码如下:
NBK-RD8x3x Demo Code(PWM).zip
(8.01 MB)
视频如下:https://www.bilibili.com/video/BV1CD4y1e7uL/?vd_source=379505f5c723a533bd2f5f97bf385084
|