使用一根数据线控制全彩LED灯!单总线LED使用指南
<p><span style="font-size:16px;"> 相信大家学习单片机的第一课就是点亮第一盏LED灯了吧,初次点亮LED的时候的心情肯定是很激动的,可以操控眼前这个小小的芯片完成自己编写的指令,顿时感觉到很奇妙。初次了解之后便会激发我们的探索精神,当学习了PWM之后,控制RGB彩灯随意调出千变万化的颜色肯定不再是难事,用在各种项目上,RGB灯会让作品更加鲜艳动人。在这美丽的背后,其实隐藏了很多的科学道理,RGB灯的颜色能千变万化的原因是因为其内部集成了3个独立的3原色灯珠,然后使用PWM波控制每个灯珠处在不同的亮度,便可以得到不同的色彩。但是一个RGB灯可能会占用多个端口,想控制很多个RGB灯便是有些难度,好在随着集成工艺的发展,这一切不再是问题,如今的工艺促使了一种新型灯珠的出现,那就是单总线LED。</span></p><hr />
<p><span style="font-size:16px;"> 简单点来说就是这种类型的灯珠内置了一个驱动电路,它控制着灯珠发出的颜色,并且有一个数据输入口,意味着我们可以往在这个灯珠里面输入数据,然后灯珠内部的电路就会驱动的灯珠发出我们想要的颜色。这个电路呢还有一个数据的输出口,也就是说它可以将接受到的数据再次发送出去,送给下一个灯珠的输入,所以这使得所有的灯珠都可以连在一起,只需要使用一个IO口控制,这就相比传统的RGB灯节省了很多的端口。<br />
这种类型的灯珠主要的核心就在它里面集成的那样一个驱动电路,这种类型的驱动电路有很多种,例如常见的WS2811,2812,SK6812等等,所以用其制作完成的灯珠一般都使用驱动电路的名字来命名。对于灯珠的大小型号呢,则有很多种类,例如5050,3535以及2020等封装,大家搜索的时候,搜索驱动电路的型号加上封装型号就可以找到想要的单总线LED了。下面是WS2812采用5050封装的图片。<br />
<img alt="" src="https://b05.ickimg.com/201907/75d1551485bc534452a9cbce3121319d.png" /><br />
本文会就WS2812这款最常用的驱动芯片来讲解其的控制方法以及在最后我会写一些控制这类单总线LED的方法。<br />
由于是单总线通讯,自然没有时钟信号线,所以通讯的时序变得非常重要,我找到一份WS2812的数据手册,查看到了其中提到的输入数据时序图。<br />
<img alt="" src="https://b04.ickimg.com/201907/2a5fe80c32bb1948673e441ab6bbe51a.png" /><br />
<img alt="" src="https://b03.ickimg.com/201907/b8f7905164be8a4b7c9dd83276e0f770.png" /><br />
可以看到,2812芯片对着时序有着较为严格的需要,所以对于0码和1码,我们需要严格控制单片机延时的时间。并且这款芯片的时序大概都在纳秒级的延时,所以对于单片机的要求还是比较高的,我采用的是增强型的51单片机,速度上足够完成纳秒级的延时。<br />
下面看到的数据的输入方法,可以看到每个数据包都是24bit长,也就是3个字节,发送完第一个24bit数据包之后就是接着发送第二个,可以看到在D2线上,第一个24bit数据包自动被忽略了,这是由于WS2812的转发机制,在其接受到第一个完整的24bit数据包之后,再接受到的数据包他会自动将其发送给下一个灯珠,这就是为什么可以一根线控制所有LED灯的秘密。并且WS2812芯片还有锁存的功能,也就是说送一次数据后,在下一回改变颜色之前都不需要再送数据了,内部的锁存电路会自动记住当前的颜色值,并控制灯珠一直保持着色彩。<br />
<img alt="" src="https://b02.ickimg.com/201907/d59d2d0bbfa17d81340da0544aedc6ea.png" /><br />
对于每一个24bit数据包,其格式如下:每一个字节都表示着颜色的亮度,从高位到低位分别是绿色(G),红色(R),蓝色(B),控制这三个颜色的亮度,我们就可以得到千变万化的色彩。<br />
<img alt="" src="https://b01.ickimg.com/201907/10b178ebbc31275a8f7d8a6ccbe458ed.png" /><br />
了解到了数据包的格式,数据手册里面还给了一张应用电路的图片,很好的说明了这种单总线LED的连接方法。<br />
<img alt="" src="https://b02.ickimg.com/201907/0baa276a532dea6b5ea246565ec1d8d3.png" /><br />
看完了数据手册,下面就是对单片机编程,使其可以输出对应的波形了!</span></p>
<p><span style="font-size:16px;">首先是对发送0码和1码的程序编写,由于需要用到纳秒级的延时,我使用空语句来进行软件延时,下面是发送0码和1码的代码截图。我这里是使用的STC15系列单片机,使用内部时钟11.0592MHZ,如果有使用相同单片机的朋友请直接参考我的代码,如果你的单片机类型不一样或者时钟频率不一样,最好使用示波器或者逻辑分析仪来得到精确的延时。<br />
<img alt="" src="https://b02.ickimg.com/201907/08603d2d3834e38dc06400c2b4721bc3.png" /><br />
完成了发送0码和1码之后,接着就是发送一个字节了,核心思路就是每次判断字节高位的值来决定发送0还是1:<br />
<img alt="" src="https://b04.ickimg.com/201907/04ee041722dd6b811929c1b808e8cc42.png" /><br />
经过简单的编程,所有代码就完成了,简单的写了一个程序,让前三个灯亮起,呈红色:<br />
<img alt="" src="https://b01.ickimg.com/201907/f2783b926f82722948f91f8554c28dc7.jpg" /><br />
其实WS2812的编程较为容易,下面就来说一些我的改进地方。<br />
我编写了一个使用串口控制RGB灯的程序,就是我可以在串口上发送数据,实时的控制每个LED灯的颜色,这样会方便后期一些动画效果的控制。我定义了一个数据格式,一个数据包含有5个字节,分别是帧头,LED灯的编号,红色(R)亮度值,绿色(G)亮度值以及蓝色(B)亮度值。例如我想要控制第五个灯变成最亮的白色,我就发送<br />
FFH 05H FFH FFH FFH 就可以了<br />
其思路就是当串口收到帧头之后,就开始读取灯的编号以及各个颜色的亮度值,然后再发送给LED灯珠即可。最后我会附上我的代码,供大家下载。</span></p>
<p><span style="font-size:16px;"> </span>**** Hidden Message *****</p>
<p>氛围灯 自己闲暇之余 还是可以DIY一下的 </p>
<p>51单片机的RAM较少,如果WS2812较多,控制就比较麻烦了。</p>
本帖最后由 mcza30 于 2019-10-17 21:53 编辑
<p>数据线可以有多长?</p>
<p>真心不错的分享啊、</p>
<p>感谢分享!!!!!</p>
<p>不错</p>
<p>好分享,可以做LED时,参考一下、</p>
好东西,值得参考 好东西,值得参考 <p>WS2812这个芯片最大能复联多少</p>
好东西,值得参考 <p>好资料,值得参考</p>
<p>123来学习</p>
u8 RGBALL;会报错!led.c(4): error C129: missing ';' before 'RGBALL' 1234 <p></p>
<p>学习一下</p>
<p></p>
<p>写的真好呀</p>
<table cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td id="postmessage_2976091">
<p>好分享,可以做LED时,参考一下、</p>
</td>
</tr>
</tbody>
</table>
页:
[1]