23349|26

1239

帖子

66

TA的资源

纯净的硅(中级)

楼主
 

单片机软件设计1-使用SPI+DMA驱动WS2812B型LED [复制链接]

 
 
本帖最后由 dql2016 于 2017-4-15 19:57 编辑

最近太忙了,实在事不好意思,今天抽空分享一下如何使用STM32CubeMX快速配置SensorTile的SPI接口,用来驱动WS2812B型全彩LED。参考了网友zoomdy的帖子http://www.stmcu.org/module/forum/thread-610279-1-1.html,在此对zoomdy无私的分享精神表示感谢。





















下面事它的时序图,十分特殊,相当于是用不同脉宽的PWM信号来表示它的一个位,虽然灯珠电气参数要求的电压比SenSorTile的3.3V要大一点点,但实测还是能完全驱动的,只需三根线(电源需用5V,地线,信号线)即可驱动,理论上可“无限”级联,实际上级联过多时,信号会产生畸变,且功率还是非常大的,每颗灯珠最多60mA电流,因此要选用合适的电源才行。
使用SensorTile的SPI来模拟它的时序,SPI配置为8位数据模式,假设其传输速率为b Mbit/s,即b/8 MB/s=b/8 Byte/us,传输一个字节需要8/b us,用1字节的SPI数据来表示WS2812B的一位数据。假设SPI发送的1字节数据中连续“1”的个数为n,按照时序要求,对于1码:那么n需要满足如下关系:n/8 * 8/b~(0.85us+/-150ns);对于0码:那么n需要满足如下关系:n/8 * 8/b~(0.4us+/-150ns);考虑到信号的上升沿等因素,SPI发送的1字节数据其最高位均取“0”。这里我配置SPI速率为1Mbit/s时,SPI发送的1字节数据0x70(0111 0000)表示WS2812B的0码,SPI数据0x7C(0111 1100)表示WS2812B的1码。一颗WS2812B需要24位数据(按照绿-红-蓝顺序,高位在前)。
STM32CubeMX对SPI的关键配置如下:






如下图Adafruit_NeoPixel.c文件,先编写一个发送8个位的函数,使用了DMA:

然后是发送24个位的:



我在底层驱动的基础上移植了Arduino平台的Adafruit_NeoPixel库函数,提供丰富的应用函数,如彩虹、呼吸等效果。
这是Adafruit_NeoPixel.h文件内容:

使用时只需配置好SPI后把下面2个文件添加进工程即可:

在main函数调用初始化后,即可愉快的玩耍了:


效果图见此帖:https://bbs.eeworld.com.cn/thread-525615-1-1.html

附上工程文件:
SensorTileProject.rar (6.19 MB, 下载次数: 7072, 售价: 1 分芯积分)



最新回复

感谢大佬分享   详情 回复 发表于 2021-8-28 14:54
点赞 关注(4)
 
 

回复
举报

1

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
谢谢分享!!!
 
 
 

回复

13

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
好想法,学习一下
 
 
 

回复

41

帖子

0

TA的资源

一粒金砂(中级)

4
 

谢谢分享!!!正想找这个。
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

5
 
谢谢楼主分享
 
 
 

回复

16

帖子

0

TA的资源

一粒金砂(初级)

6
 
谢谢楼主分享
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

7
 
借鉴下
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

8
 
谢谢啦, 移植看下效果
 
 
 

回复

33

帖子

0

TA的资源

一粒金砂(初级)

9
 
谢谢分享
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

10
 
来学习下这个
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

11
 
学习学习,谢谢分享
 
 
 

回复

2

帖子

2

TA的资源

一粒金砂(初级)

12
 
SPI传输  每传输8位中间有间歇哈?这个弄?
 
 
 

回复

1

帖子

1

TA的资源

一粒金砂(初级)

13
 
感谢分享
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

14
 
哇感谢大佬!一只萌新路过
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

15
 
昨天看了大佬的教程,今天把东西弄出来了,过来补充一些。首先一开始不太理解大佬说的0码跟1码,后来抓了波形才懂,其实1码最左边的0,作为是上一个数据的补充,0码同理。大佬这一招很妙!另外大佬spi的速率应该是不对的吧?1Mbit/s的话8位数据的时间就是8us远超一个ws2812数据码的周期。所以一开始移植的时候(一开始为了节约时间没有仔细研究大佬说的话)死活调不通,后来25us发现spi速率配错了。emmm我自己配的速率8位数据1.25us直接跟他对应起来,每一位就是的时间1.25/8,速率就是8/1.25=6.4M。为了这6.4M我还专门去调了stm32f4的总线时钟频率,结果当然是降频了,感觉有点得不偿失。总之还是为了提醒大家学习要多专研啊!也给大家提提醒,顺便谢谢大佬的指教了!

点评

楼主的这种方式有些浪费内存资源 使用SPI最节省内存的方法是用3bit来实现ws2812的一位 SPI时钟在2.5Mbps左右时可以用100=0,110=1 这样ws2812b的24位数据可以使用9个字节实现 具体可以看一下我的贴子  详情 回复 发表于 2019-1-10 19:37
 
 
 

回复

9795

帖子

24

TA的资源

版主

16
 
风狼 发表于 2019-1-10 16:55
昨天看了大佬的教程,今天把东西弄出来了,过来补充一些。首先一开始不太理解大佬说的0码跟1码,后来抓了波 ...

楼主的这种方式有些浪费内存资源
使用SPI最节省内存的方法是用3bit来实现ws2812的一位
SPI时钟在2.5Mbps左右时可以用100=0,110=1
这样ws2812b的24位数据可以使用9个字节实现
具体可以看一下我的贴子
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

17
 
littleshrimp 发表于 2019-1-10 19:37
楼主的这种方式有些浪费内存资源
使用SPI最节省内存的方法是用3bit来实现ws2812的一位
SPI时钟在2.5Mbp ...

嗯嗯确实,谢谢指教。
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

18
 
好东西啊,经典
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

19
 
这个历程比较巧妙的用多位SPI的数据来达到高电平长短的标识,来实现WS2812的时序要求,最有意思的是能够移植arduino的库,我用过那个库确实很炫,厉害厉害,哈哈哈哈
 
 
 

回复

869

帖子

0

TA的资源

禁止发言

20
 
楼主威武,强烈支持……
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表