Java教程

关于使用WS2811点灯

本文主要是介绍关于使用WS2811点灯,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

今天某位网友突然提到说需要使用ws2811点亮一条灯带,想到之前有专门研究过此方面内容,不免拿出卖弄一下。

首先我们来研究一下,为什么只需要一个GPIO口就能点亮一串WS2812灯珠,而且每个灯珠都可以使用256*256*256色?

从datasheet来看(这里再吐槽一把,也许是原理太简单,不同网站下的ws2811的参数居然不同),就是按比特位给每个灯发送数据,每个灯都取走第一个颜色(24位),取完自己的颜色后,将剩余颜色向后传递,依次递推。因为用一段高低电平的持续实际分别0和1,表示所以群里说的SPI+DMA比NOP速率高,是不太可能的,点灯的速率只和需要点灯的数量有关(反正每个灯1.25us左右),和采用点灯的方案关系不大。如下是截取不同版本datasheet里的说明:

     

看,虽然每个文档都写TH+TL值相同(1.25us),但有些文档里面0的持续时间(0.35us+0.8us)是可以比1持续时间(0.7us+0.6us)短的。虽然可以实现在150ns的误差范围内使其满足1.25us的需求,但严格按照数据手册编程的话,还是有所差异的。

接下来,我们看看怎么实现点灯,最直接的想法肯定是直接控制IO口,并精确调整延时,这对板子性能要求太高,一般的板卡都不太可能做到;退而求其次,用NOP来做延时,这个对板子的性能要求没有那么高,大多数开发板可以做到。

最近在读RT-thread中的WS2811源码,感觉非常巧妙,具体是怎么实现的呢?答案是利用SPI接口。

传统SPI采用4根信号线,分别为CLK、CS、SDI和SDO。SPI是串行通讯协议,也就是说数据是一位一位的传输的。在CS片选之后,由主设备的SCLK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输。数据输出通过 SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取,连续8次时钟信号的改变(上沿和下沿为一次),才能完成一个字节数据的传输。输入也使用同样原理。

如上所述,当没有时钟变化时,SDO口的电平是相对保持的(无所谓正反相位),因此可以使用SPI总线发送特定数据分别表示0和1。

在RT-Thread中选取

可以看到相关代码如下:

这是在初始化SPI,使其时钟为13.333MHz,每个时钟周期可以传送1bit数据,耗时75ns。

接下来,采用SPI传输两个字节来实现WS2812上的1个位数据。

可以看到,bit0使用1111 1000 0000 0000,bit1使用1111 1111 1110 0000,分别对应高低电平时长。

T0H=0.375us

T0L=0.825us

T1H=0.825us

T1L=0.375us

基本上在datasheet的标注范围内。

函数ws2812_write_rgb_to_node

实现单个灯珠颜色的写入。

函数ws2812_write_rgb_to_all

次第写入灯链中每个节点的数据

 

接下来实现通过SPI发送数据

对于调整灯链颜色的需求,因为每次变换颜色,时间间隔至少50us,对于开发板来说,这个实现起来就比较简单,在这里也不用特别提及了。
---------------------
作者:tobot
链接:https://bbs.21ic.com/icview-3200798-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

这篇关于关于使用WS2811点灯的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!