近几年,PC领域随着电竞类的键盘鼠标加灯的风潮,各种带有花式“光污染”的PC外设被推到市场上来,这些“神光同步”的PC外设背后离不开高性能MCU去协助点灯这项工作,反正神光一亮性能立马提升10%。
在灯光方案的选择上,WS2812这类单线制串行LED灯珠被应用的最广,而且很多LPC Inside的键鼠设备也许正躺在各位臭打游戏的桌面上,所以本文以WS2812为基础,逐一介绍如何用LPC单片机上的不同的外设实现同样的驱动WS2812这类串行LED灯带。
这个系列我计划分成3篇,这是第一篇讲基础和SPI的方式实现,第二篇讲SCT,EZH的实现,双核点灯,第三篇讲如何移植NeoPixel-KnightRider到MCU,实现花式点灯。
首先介绍下WS2812
WS2812是一种5050封装,集成了电流控制芯片的低功耗的RGB三色灯,是各种LED灯带的灵魂所在。WS2812采用串行级连接口,可以实现256级亮度的三基色颜色显示即完成16777216种颜色的显示且扫描频率不低于400Hz,刷新速率30帧/秒时,级连数不小于1024点,串行数据发送速度可达800Kbps。

WS2812灯带在淘宝上有各种规格:66灯的,144灯的,密封的5m,密封的1m,裸露的5m,裸露的1m,等等。

WS2812 功能引脚

WS2812 级联

WS2812 时序波形图

WS2812 RGB数据结构

如何用LPC55S69 驱动WS2812
了解完WS2812的时序后,我们分析下LPC55S69上的外设,目前评估下来,可以用LPC55S69上的SPI,SCT定时器,EZH或者用双核里的那个小核控制GPIO口 这四种方案来实现,本文会介绍SPI的方式,之后的文章会分别介绍SCT,EZH以及双核实现。
利用LPC55S69的SPI接口实现WS2812的控制
实现分析
由分析WS2812的时序可知,0码和1码代表的是占空比的不同,我们可以用SPI传输的8个bit中的1和0的个数不同来表示0码和1码,即0码可以是由 01110000 来表示,1码可以是01111100来表示。
WS2812的基础通信时钟是800kbps,SPI是8bit传输的,所以SPI的时钟频率应该定在800kbps x 8 = 6.4Mbps

这样我们就可以建立一个WS2812显示颜色用的数组uint8_t g_WS2812TxBuf[WS2812_PIXELS*24+100],x24 的原因是一个WS2812需要RBG 3个色元,各8bit。
虽然用SPI控制WS2812比较简单,但是各位看官也看到了,这种办法是比较吃RAM的, 还好LPC55系列的RAM都不是一般的大,足够应对。
复位
WS2812的50uS以上的低电平复位信号是比较容易实现,可以通过控制GPIO的高低状态就可以实现。当然我们也已利用SPI发送数据0实现,LPC55的这个demo我们是用SPI发送0数据产生复位信号的,我们把用于SPI发送的数据额外多设置100个字节,开始的100个字节填充0,这样我们就可以产生复位信号了。

时钟精度
结合LPC55的SDK,为了得到比较精确的6.8Msps的SPI传输速率,我们得把MCU的主频提升至比较高的级别,这里我们用LPC55上的96MHz的高速FRO作为MCU的时钟源,这样可以达到比较好的能耗平衡。
将SDK里SPI初始化中关于时钟部分改成6800000Hz。
在96MHz基础上去得到6.8MHz是肯定有偏差的,实际我们得到的SPI时钟频率是6.857MHz,好在WS2812实际允许的150nS的偏差的。我们这种方法实际是可以完美驱动WS2812的。
当然如果是强迫症,我们可以用LPC55上的PLL来生成完美匹配6.8MHz的频率的主频,比如68MHz,136MHz等给内核用。这样做无非是略微增加了一点功耗。
用轮询(Polling)的方式实现SPI数据传递给WS2812
轮询的方式实现比较简单,我们传输的是固定的数据,所以我就没有用SDK的标准API,自己实现了非常直接的发送函数

点灯前别忘设置灯的个数
如果我们用的WS2812灯带有8个灯,在drv_ws2812_spi.h里修改LED的数量

接下来,如果我们要把WS2812按照流水灯的方式,显示RGB 三原色。则按照顺序,轮流修改g_WS2812TxBuf中的数据组合即可。

效果

网友评论