数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 23756|回复: 14

[other] (小白向)详解ws2812驱动

[复制链接]
发表于 2019-11-25 15:04:02 | 显示全部楼层 |阅读模式
本帖最后由 YvonneOH- 于 2019-11-25 15:14 编辑

WS2812B是一个集控制电路与发光电路于一体的智能外控LED光源。其外型与一个5050LED灯珠相同,每个元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路,还包含有高精度的内部振荡器和12V高压可编程定电流控制部分,有效保证了像素点光的颜色高度一致。
通讯协议说明:
数据协议采用单线归零码的通讯方式,像素点在上电复位以后,DIN端接受从控制器传输过来的数据,首先送过来的24bit数据被第一个像素点提取后,送到像素点内部的数据锁存器,剩余的数据经过内部整形处理电路整形放大后通过DO端口开始转发输出给下一个级联的像素点,每经过一个像素点的传输,信号减少24bit也就是说,第一颗灯珠将读取从MCU传输过来的所有数据,取其中24位作为自身数据,并将其余数据整形后向后传递,以此类推,直到数据传送完成。之后,MCU发送一个>=50us的低电平,ws281x芯片复位,重新开始第二次数据传输。


这种通信方式大大节省了所需MCU的引脚,但是,缺点也很明显。数据的0位和1位通过高电平和低电平的时间来控制,精确度在纳秒级别(0位和1位各占1.25us),对低速MCU极其不友好。

参看时序波形图可以发现,0位和1位都是通过一个1.25us+-300ns(也有150ns或者600ns的,300ns比较常见)左右的信号来实现
0Bit:三分之一的高电平加上三分之二的低电平
1Bit: 三分之二的高电平加上三分之一的低电平
Reset:超过50us的低电平
每一芯片单元的24Bit数据按照G8R8B8位来编码,想要实现相应的颜色可以参考RGB色表。


引脚:
芯片有四个引脚Vcc Gnd D0 D1

驱动方法:
目前大概有三种驱动方法:
l  GPIO配合机器空周期直接驱动。
l  PWM+DMA驱动
l  SPI+DMA驱动
第三种没做过实验,这里就不讲了。
1.GPIO配合机器空周期直接驱动稳定性比较差,需要配合示波器测出准确的延时。而且,数据错乱的概率比较高,在不同的板子上一致性也不好。如果MCU的电平翻转速度达不到纳秒级,这种方法必失败。
2. PWM+DMA驱动也是我采用的方法。我们知道每一位的特征周期为1.25us。这个间隔对应于800kHz的频率。此外,仔细观察协议,我们可以注意到唯一改变的是每个周期的高部分。它类似于一个脉冲宽度调制信号,可以做一个800KhzPWM波去驱动。
理论上说到这里灯就已经可以亮起来了,但我还是引入了DMA,简单来说,DMA 传输将数据从一个地址空间复制到另外一个地址空间。当CPU 初始化这个传输动作,传输动作本身是由 DMA 控制器来实行和完成。DMA的数据传输不占用CPU
想象一下,当CPU传输成百上千个LED的数据,突然有中断发生,那么这组数据就会发生传输错乱。而当数据量很大时,CPU的占用率会非常高,这样就不能执行其他任务了。DMA可以把CPU解放出来。

看看代码:

代码后面会发,面对小白向的旁友,为了尽快驱动起来,我就说一下包装好的函数:

WS2812_ledsingle_send1(uint8_t color[][3], uint8_tcolor[][3])

这个函数有两个参数:

uint8_t color[][3]:这个是一个N*3的数组,N就是颜色组数,{R,G,B}3个数就是RGB

大概长这样:
uint8_t myrgb[9][3]={{0,0,0},{32,0,0},{32,0,0},{32,0,0},{32,0,0},{32,0,0},
                             {32,0,0},{32,0,0},{32,0,0}}

不过这里有个BUG,我发现前几帧可能会被吞掉,为了保证稳定,第一个数组为空.

写完了之后灯就可以亮起来了。




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 5家元 +57 收起 理由
jf201006 + 20 謝謝分享
hongo + 12 優秀文章
不长叶子的树 + 10
wc5095928 + 5 厉害 谢谢分享
xmmz + 10

查看全部打赏

发表于 2019-11-25 15:21:55 | 显示全部楼层
厉害 谢谢分享
回复 支持 反对

使用道具 举报

发表于 2019-11-25 15:28:38 | 显示全部楼层
@ifm 直接上硬货,ws2812驱动深度分析:http://bbs.mydigit.cn/read.php?tid=2622343
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-25 15:36:59 来自手机浏览器 | 显示全部楼层
不长叶子的树 发表于 2019-11-25 15:28
@ifm 直接上硬货,ws2812驱动深度分析:http://bbs.mydigit.cn/read.php?tid=2622343

这个不错哦
回复 支持 反对

使用道具 举报

发表于 2019-11-25 15:41:21 | 显示全部楼层
省去总线的代价就是高速和不稳定
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-25 15:51:35 来自手机浏览器 | 显示全部楼层
落花萧然 发表于 2019-11-25 15:41
省去总线的代价就是高速和不稳定

是这样子的
数据传输确实不够稳定,不过这种灯带也无所谓了
回复 支持 反对

使用道具 举报

发表于 2019-11-25 22:38:47 | 显示全部楼层
不过这里有个BUG,我发现前几帧可能会被吞掉,为了保证稳定,第一个数组为空:lol:

http://bbs.mydigit.cn/read.php?tid=2406878
回复 支持 反对

使用道具 举报

发表于 2019-11-29 13:07:01 | 显示全部楼层
我怎么看不到图片呢?:cry:
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-29 14:43:16 来自手机浏览器 | 显示全部楼层
zoro 发表于 2019-11-29 13:07
我怎么看不到图片呢?

奇怪  我也看不到了
怎么回事
回复 支持 反对

使用道具 举报

发表于 2019-11-30 09:39:35 | 显示全部楼层
不同厂家的时序稍有差别,最小最大时间,
回复 支持 反对

使用道具 举报

发表于 2019-12-2 00:28:43 | 显示全部楼层
这个好呢有创意,值得学习
回复 支持 反对

使用道具 举报

发表于 2019-12-5 21:41:32 | 显示全部楼层
最好的办法还是用SPI+DMA驱动好点,一次能发送16bit。这种东西一定要硬件化,不要占用CPU时间。当然也可以单独哪一个低性能的MCU做从机,主机通过硬件串口或者SPI向从机写数据,从机根据数据只做驱动LED这项工作。
或者使用FPGA,CPLD设计一个硬件接口,一边通过SPI或者并口与MCU连接,一边与LED连接。驱动方式就跟液晶屏一样,MCU向VRAM写入数据,内部时序逻辑电路自动将内容变为LED可接受的数据脉冲。
回复 支持 反对

使用道具 举报

发表于 2019-12-6 01:09:38 | 显示全部楼层
这玩意硬伤是不同厂家高低电平时间也不大一样
回复 支持 反对

使用道具 举报

发表于 2020-7-14 21:52:12 | 显示全部楼层
不错,学习了
回复 支持 反对

使用道具 举报

发表于 2020-9-3 12:50:47 | 显示全部楼层
不过确实使用起来比较方便    三根线即可
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-22 02:10 , Processed in 0.327601 second(s), 17 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表