欢迎关注BUG记录知乎专栏和BUG记录公众号,关注BUG记录公众号回复2812获取本文的参考单片机程序以及STM32CubeMx的安装包和库文件
之前曾写过SPI协议的verilog实现,其实单片机也有很多地方用到了SPI,今天我们说一个比较冷门的SPI用法——控制WS2812灯带。
本文主要介绍STM32CubeMx的使用,WS2812灯带的控制。通过WS2812的例程,简单展示STM32CubeMx的方便,快捷
玩过单片机的人或多或少都知道STM32单片机,而STM32单片机因为其相对而言强大的性能,操作也变得较为复杂;为了让更多的人能够快速的上手STM32,减少各种外设内设寄存器操作的复杂干扰,官方推出了STM32CubeMx,能够以图形化界面,设置好相关的内部寄存器,使开发者不被底层操作束缚。
WS2812,如上图,它可以显示256级亮度,完成16777216种颜色的全真色彩显示。用它可以完成各种绚丽的色彩显示。但是,它的控制也有一点麻烦,通过一根线上占空比不同区别0-1,将色彩的RGB二进制代码发送到WS2812显示
RGB一共要发24位,而输入码型却不是简单的高低电平,它有较为复杂的时序要求;为了解决这个问题,有人想到了“曲线实现”的方法,通过SPI输出不同的数据来实现对WS2812的控制。
举例来说,假设SPI发送速率为4.5MBit/s, 那么发送1bit所占的时间为1/4.5 us,大概为0.22us; 那么,我发送0xf0时,前4位数都是高电平,占时0.88us,满足了T1L的高电平时间,这时候有人会说你低4位都是低电平,没关系,满足条件后的低电平默认为空闲状态,实验证明这确实也不会影响最终效果。
同样,发送0xc0,满足T0L的时序要求,而现在,需要做的就是使用STM32CubeMx完成相关的寄存器设置;
这个地方需要注意,因为SPI的速率较高,内部的8MHz时钟可能无法满足,这个时候需要启用外部晶振,再经过PLL倍频,操作如下:
PLL的倍频操作如上图,可以适当做调整。
设置好Debug,否则没办法Debug代码;这个地方根据自己的调试器做选择;
选用SPI1,模式选择仅主发送,然后在Parameter Setting里面,选择MSB First,上面的PLL设置倍频后,SPI的时钟为72MHz,经过预分频16后,SPI的波特率为4.5MBit/s,这个地方需要选择CPOL和CPHA,关于CPOL,CPHA的内容可以查看配置芯片寄存器的SPI通信协议的verilog实现(一)
这个地方,添加一个SPI1_TX的DMA,具体设置如上;
点击Project Manager子标签,设置如同上面
注意选择正确的Toolchain,然后点击右上角“generate code”,就可以生成相关的工程文件啦;
里面的通信控制主要是使用了HAL_SPI_Transmit_DMA函数,这是HAL库自带的库函数,使用这个库函数发送数据;
这个是RGB转成SPI发送需要发送的数据;转换的过程比较简单粗暴,没想什么巧法子。
这个是WS2812总的发送程序,其实也就是结合了上面的两个程序,到此WS2812驱动就基本写完了,具体细节可以关注BUG记录公众号回复2812获取本文的参考单片机程序以及STM32CubeMx的安装包和库文件
注意,STM32CubeMx生成的代码里想做修改,需要在“/* USER CODE END WHILE */”和“/* USER CODE BEGIN 3 */”中间写,这样如果使用STM32CubeMx重新修改设置,重新生成代码不会抹掉用户做的代码修改;
maxs-well/ws2812_by_SPI_DMA_STM32github.com这是本文用到的代码,除去ws2812.c和ws2812.h,其他的源代码基本是STM32CubeMx生成,如果想看本文用到的STM32CubeMx工程,安装包和库文件,欢迎关注微信公众号BUG记录(BugRec),回复2812获取资源。
如果有更好的方法方案可以留言一起谈论,欢迎大家点赞收藏留言讨论交流。
万物皆可卷积:配置芯片寄存器的SPI通信协议的verilog实现(二)- Verilog实现讲解zhuanlan.zhihu.com