您尚未登录。

楼主 # 2022-01-22 16:28:15

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

[记录]使用SPI驱动WS2811

市面上常见的2款串行可编程控制LED方案,分别是WS2811和WS2812。
    其中,

    [1]WS2811是芯片,常规供电为12V,按理说,驱动距离会远一些。

    [2]WS2812是灯珠,把可编程芯片内嵌在灯珠里面,常规供电5V,按理说,驱动距离相对短。

   

    相信很多朋友都在51单片机上面驱动过这个芯片,使用方法是:IO模拟单总线时序,达到传输RGB数据的效果。

    因为WS2811/2812驱动时序,是us级的,IO模拟的方法,过度依赖CPU,这种做法实在不合理。

    正确做法应该是借助片上的通讯外设,如UART/SPI等,兼容WS2811/2812的时序,腾出CPU资源,并且提高灯带驱动的稳定性。



    本文章阐述,使用SPI驱动WS2811的思路。

    先看手册:   

    ![image-20220122160847782](image-20220122160847782.png)
        image-20220122160847782.png

    ![image-20220122160959434](image-20220122160959434.png)
        image-20220122160959434.png

    从WS2811的手册,可以得知( 高速模式下 ):

    [1]这款芯片支持2种驱动速度:分别为高速模式和低速模式。

    [2]对单总线送'0'码和'1'码,需要使用T0H / T1H / T0L /T1L搭配。

    [3]搭配出来的'0'码和'1'码所占用时长皆为 2.5us。

    [4]T0H = T1L = 0.5us

    [5]T1H = T0L =2.0us = 4 * T0H = 4 * T1L

   

    因此,SPI总线的驱动时钟,一个时钟脉冲的周期不能大于 T0H / T1L ,也就是不能大于0.5us。

    我们试着就让SPI总线一个时钟脉冲的周期就等于0.5us,Tspiclk = 0.5us。

    那么,频率Fspiclk = 1 / Tspiclk  = 2MHz。

    这种情况下,如果想要送RGB888数据中的 1 位 数据 到WS2811,SPI总线需要发出5个位的数据:

○  1 : 00001 

○  0 : 11110

    如果要发1字节数据(8个位),如R = 0xF0,对应二进制为:

	1111 0000

    那么SPI应该发出这样的数据:

 	00001 00001 00001 00001 11110 11110 11110 11110

    对其进行组合,可以得到5个字节:

    0000 1000 0100 0010 0001 1111 0111 1011 1101 1110

    所以,SPI应该发送的数据为:

	0X08 		0X42		0X1F		0X7B		0XDE

    同理,对于R 、G、 B都可以这样操作。

    那么,也就是说,想要给一颗WS2811输送RGB888数据,需要发送5*3 = 15个字节

最近编辑记录 LinjieGuo (2022-01-22 16:30:37)

离线

楼主 #1 2022-03-07 14:13:06

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: [记录]使用SPI驱动WS2811

时隔多日,回来续帖。
    前面知道了原理,接下来,我们得生成一个color表。
    color表的结构应该是这样:
   

uint8_t ws2811_color[256][5]={......} 

    其中,256对应一中颜色分量的颜色深浅,因为RGB各占8bit。
    以下是我针对1楼的时序,生成的color表:
    color_map_ws2811.c
    color_map_ws2811.txt
    下一步是借助color_map_ws2811.c文件,编写CH579M的驱动代码!

最近编辑记录 LinjieGuo (2022-03-07 14:15:59)

离线

楼主 #3 2022-03-10 08:39:29

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: [记录]使用SPI驱动WS2811

xboot 说:

哈哈,大哥果然神速。
我昨天调试了半天ws2811。
怎么搞都不行,后面才发现。12V没接......

离线

楼主 #4 2022-03-10 09:02:39

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: [记录]使用SPI驱动WS2811

xboot 说:

另外,可以把dma怼上去。
我是这样搞:

#define CHIP_NUM  100
typedef strut{
  uint8_t rst[200];    //0.5us *200 = 100us 
  uint8_t frame[ CHIP_NUM ][3][5];
  //3 代表颜色分量,R / G / B
  //5 颜色数据,5字节SPI数据描述一个分量的颜色深浅
}ws28xx_t,ws28xx_pt;

然后定时使用DMA将帧内存通过SPI发送出去就可以了。

最近编辑记录 LinjieGuo (2022-03-10 09:04:32)

离线

楼主 #8 2022-03-10 09:25:55

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: [记录]使用SPI驱动WS2811

对于上面我使用的WS2811的情况,2M SPI CLK,
情况如下:
(1)T0H = T1L = 0.5us = 500ns
(2)T1H = T0L =2.0us = 4 * T0H = 4 * T1L
看了你的WS2812手册里面给了个范围,
我们以WS2812B为准,将SPI CLK提升到4M。
那么,周期变成一半。
(1)T0H = T1L = 0.25us = 250ns
(2)T1H = T0L =1.0us = 1000ns =4 * T0H = 4 * T1L

观察了一下,完全符合WS2812B的时序要求。
(WS2812的数据传输速度是800KHz,WS2811(400KHz)的2倍)
所以,你至少使用4M的SPI CLK,才能驱动WS2812。

最近编辑记录 LinjieGuo (2022-03-10 09:26:48)

离线

楼主 #9 2022-03-10 09:47:48

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: [记录]使用SPI驱动WS2811

@xboot
分析的没错。
还有个地方需要注意。
那就是复位时序的时间长短,
有很大区别。
WS2812B需要280us以上
WS2811 反而只需50us以上。
(可能是WS2812B的传输数据速度快,为了确保稳定性,把复位时长提高?)

最近编辑记录 LinjieGuo (2022-03-10 09:49:24)

离线

楼主 #13 2022-03-12 09:52:01

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: [记录]使用SPI驱动WS2811

xboot 说:

使用5bit,测试下来,发现可靠性偏低,感觉有必要搞成8bit,或者16bit,反正SPI时钟速度不是瓶颈。还有感觉想要搞通用时序,估计可靠性都好不到哪里去,最优的方式,还是用可配置的8bit或者16bit方案。

2812没有测试过,
值得一提的是,我这里使用WS2811芯片,
测试情况是,没有问题。
随时热拔插,瞬间就点亮并且呈现目标颜色。不存在乱闪的问题。
我现在看看搞一个8bit/16bit的表格出来。

离线

楼主 #14 2022-03-12 10:03:11

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: [记录]使用SPI驱动WS2811

这是我测试到的波形,看起来数据宽度并没有绝对0.5us/2.0us,
是由于我的晶振使用内部32MHz晶振,时钟不准,但是点亮WS2811没有什么问题。
我现在看看WS2812,搞一个表出来。

(1)whycan下载
(2)站外免积分下载

最近编辑记录 LinjieGuo (2022-03-12 10:05:58)

离线

楼主 #16 2022-03-12 10:21:18

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: [记录]使用SPI驱动WS2811

我从别的网站帖子上面看到了如下信息,我根据这些信息列出理论依据。
WS2812原理与实现
裁剪帖子的部分信息,可以看到,对于WS2812,其时序要求如下:
ws2812_clk.png
(1)T0H = T1L = 0.4us    (±150ns,建立color表时,尽量不考虑误差范围,可作为芯片SPI时钟误差)
(2)T1H = T0L = 0.85us  (±150ns,建立color表时,尽量不考虑误差范围,可作为芯片SPI时钟误差)

(3)与1楼的理论同理,得:
令SPI的一个时钟周期t = 0.05us,即SPI 的f = 20MHz。

T1H = T0L = 17个SPI数据
T0H = T1L =   8个SPI数据位

但是,芯片支持误差容忍(0.15us/150ns),
所以,可以尝试:

T1H = T0L = 16个SPI数据(少1个时钟节拍,0.05us/50ns)
T0H = T1L =   8个SPI数据位

最近编辑记录 LinjieGuo (2022-03-12 10:26:12)

离线

楼主 #19 2022-03-12 11:22:15

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: [记录]使用SPI驱动WS2811

xboot 说:

综合判定下来,应该选择8bit模式,比较合理,资源也相对少一点,8bit的话,基本就可以不要表格了,直接运算就行了。

按我上面所描述的8bit处理,那么,描述一个RGB,使用24字节。
如果存在表格,按字取数,取6次就可以了。
表格不需要运行时参与,存在代码区。
我随便撸几行代码,搞一个表格出来。哈哈。

最近编辑记录 LinjieGuo (2022-03-12 11:22:44)

离线

楼主 #20 2022-03-12 12:24:28

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 581
积分: 585
个人网站

Re: [记录]使用SPI驱动WS2811

大哥,ws2812你看看这个color表行不行。

SPI CLK 20MHz

T1H = T0L = 16个SPI数据     = 0.8us
T0H = T1L =   8个SPI数据位  = 0.4us


color_map_ws2812.c

最近编辑记录 LinjieGuo (2022-03-12 12:26:45)

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn