王昱顺 发表于 2024-1-5 19:35:31

使用SPI-DMA无限驱动WS2812灯带!无需反相器,STC32F上验证成功

前言:
近来考试周,感觉复习的多了总是有点烦躁的。正好前几天看到有几个帖子在讨论W2812灯珠驱动的问题。
借此机会就写点驱动和灯效解解闷。
STC DMA-SPI 驱动 WS2812 实现:无需反相器,无限长度WS2812驱动
===(我没有那么长的灯带,理论测定,底下有理论分析依据)。
先上个效果视频:

回顾现在论坛里面的主要问题有这么几个:
1.首先是就是SPI-DMA发送数据的时候每一个8位数据之间会存在一段拉高的电平
==这个可以通过初始设置 SCLK,MISO,MOSI 为0,就可以解决了,具体原因不详。
2.大家说的特别长的灯带没法驱动
==经过验证,SPI-DMA间隔只有4.8us(较高优先级),而手册上说数据位的低电平时间不能超过20us。所以时间是完全够用的。
3.还看到梁工说可以使用四位驱动,更节省内存占用。
==我尝试了一下,可以实现。我的设定是300ns的SPI单bit周期。
此时0码是1000,1码是1110。正好对应手册典型值300ns和900ns。


300ns的准确周期我是使用了HPLL拉高频率后进行分频得到的,理论上来说常见的频率都可以这么变换到所需要的频率
以下是我的驱动时序:


可以看到0码的驱动周期为准确的300ns。


DMA的测试是通过在SPI-DMA中断里拉高测试IO口得到的:


可以看到上一个数据发送完成后,到下一个书发送开始只隔了4.8ns。


程序等我整理一下发上来,因为是套了个别的工程,分离出来需要一点时间。
注明:我的程序直接使用并不能驱动非常长的W2812灯带,因为我还没用双缓冲来做SPI-DMA。
我仅仅是验证了一下理论存在,目前可以驱动的最大长度大约在340个灯珠左右。


==文件已经上传,文件main.c文件前几行写明了注意事项。文件内基本都有注释,不清楚的可以在本贴问我。





21cnxin 发表于 2024-1-6 08:01:35

看看,学习一下

lihappy 发表于 2024-1-6 08:46:28

由于DMA缓存数据只有256字节,一颗灯占12字节。长灯都需要灯数可调,所以数据组只能以12为单位,就等于DMA每次只能缓存一颗灯,会导致灯数多了之后刷新时间会拉得很长。实验的刷3000个灯的时间基本超过1秒

王昱顺 发表于 2024-1-6 12:47:23

lihappy 发表于 2024-1-6 08:46
由于DMA缓存数据只有256字节,一颗灯占12字节。长灯都需要灯数可调,所以数据组只能以12为单位,就等于DMA ...

长灯刷新时间长很正常,不过你说的DMA每次只能缓存一颗灯我不是很理解,灯数可调完全可以做到最后一个不能被整除的灯数时再分割,而不是开始就一个一个分割。
还有一个问题是,我这个DMA最大能64K,这个是STC32F,和STC8H还是有点不一样的

神农鼎 发表于 2024-1-6 13:22:26

STC8H8K64U的 DMA 可以用 多缓冲技术,显示数据先放到 不同起始地址的 xdata,DMA送完1包,改 DMA 起始地址就行

神农鼎 发表于 2024-1-9 08:42:53

SPI方案:
只用到MOSI驱动WS2812,但由于SPI的3个信号是捆绑在一起的,MISO、SCLK不能做它用。
===将 MISO 不做其他用途;
===将 MISO管脚 先设置为对外输出0;
===MOSI 发送完成后,对外停止时输出的是 MISO 读到的状态, 0 ,这 STC-R&D 留了这么个绝活支持 WS2812B !!!

RWJ576871 发表于 2024-4-30 12:20:52

大师,初学者从哪里开始学习,谢谢!

王昱顺 发表于 2024-4-30 14:09:18

RWJ576871 发表于 2024-4-30 12:20
大师,初学者从哪里开始学习,谢谢!

可以从官方的例程开始,仔细看看技术手册
页: [1]
查看完整版本: 使用SPI-DMA无限驱动WS2812灯带!无需反相器,STC32F上验证成功