社区导航

 
查看: 1453|回复: 14

[原创] WS2812灯珠的STM32驱动方式(二)——DMA+PWM

[复制链接]

1156

TA的帖子

2

TA的资源

版主

Rank: 6Rank: 6

发表于 2018-5-6 22:48:55 | 显示全部楼层 |阅读模式
本帖最后由 通宵敲代码 于 2018-5-6 23:34 编辑

上节我们重点介绍了一下WS2812B,
这种内部集成驱动芯片的RGB灯珠,
并通过对驱动信号通信速率的详细计算,
重点说明了STM32等一众单片机通过I/O翻转方式,
控制这种灯珠的困难之处,这篇我们就介绍一下,
如何用最常见的方式来实现STM32对WS2812的控制。

常用STM32的都知道,STM32有8个定时器,
其中TIM1跟TIM8是高级定时器,TIM2345是通用定时器,
TIM67是基本定时器,当然还有个滴答定时器,
其中TIM123458都可以独立控制输出PWM波形,
TIM1跟TIM8还可以输出两组互补PWM波形,
这个功能在电机驱动中十分常用。
TIM截图20180506224832.png
STM32定时器的PWM输出功能,
是通过CNT与CCR寄存器的数值比,
直接控制对应引脚输出高低电平的,
也就是说只要我们愿意,可以用定时器直接输出36MHz的方波,
当然波形可能就不那么好看了,
不过用来驱动我们800kbps的WS2812,可以说是绰绰有余了,
TIM截图20180506225124.png

但是还有一个问题,通常情况下,
我们的WS2812不会仅仅是一个或者几个LED串联,
如果串联的LED较多的话,又会面临驱动信号的稳定性问题,
毕竟我们要不断地改变定时器CCR的数值,
来控制对应的I/O发送信号0还是信号1,
而项目中我们的单片机又不可能只是用来控制LED,
这时候我们的DMA功能就派上用场了。
这也就是我们今天要介绍的最容易想到的一种方法DMA+PWM,

TIM截图20180506225220.png




回复

使用道具 举报

1156

TA的帖子

2

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2018-5-6 22:49:12 | 显示全部楼层
本帖最后由 通宵敲代码 于 2018-5-6 23:28 编辑


上面介绍完原理,下面就是如何实现功能了,
我们直接来看程序,声明一下我们是用原子的例程移植的。
这里我们依然使用是STM32的HAL库,
没办法,用熟了,顺手,而且各种以前的资源不能浪费了不是。

首先是时钟配置,这个没什么好说的,能跑多快就多快吧。
就跟没人会希望自己媳妇丑一样。
TIM截图20180506225817.png
(哦,不好意思这段是之前用寄存器写的,拿过来用了,见谅)

下面是今天的主角,DMA+PWM的配置方式。
TIM截图20180506230104.png
先配置下GPIO吧,我们使用的是TIM2的CH1通道,
对用的PWM输出引脚是PA0,注意要用复用输出功能哦。

下面是TIM2+CH1通道的配置,注意要配置成800KHz的频率,
内核时钟72M / 90 = 800KHz,应该不难理解吧。
然后是CH1输出通道的,配置成PWM1输出模式即可,
注意电平的极性,不放心的可以用示波器抓抓波形。
TIM截图20180506230113.png

然后就是我们的DMA得配置了,要设置好数组地址跟寄存器地址
然后就是DMA传输的字节长度,传输模式等等了
TIM截图20180506230138.png

有关寄存器地址大家应该会找吧,不会的看下边,
先从Datasheet找到我们的存储器映像图表,找到TIM寄存器租的起始地址,
TIM截图20180506231215.png
可以看到TIM2寄存器组的起始地址是0x40000000,
然后找到Reference Manual里,我们需要使用的TIM2_CCR1寄存器,
TIM截图20180506231626.png
可以看到CCR1的偏移地址是0x34,所以我们需要的寄存器地址就是,
0x40000000 + 0x34 = 0x40000034,不懂得童鞋回去好好啃啃计算机原理吧,

需要的外设资源配置好了,接下来就是万事俱备只欠东风了,
下面就是我们有关LLED控制信号的处理函数了,
look,不多解释。
TIM截图20180506232012.png
上图最后面那个bug,是之前原子的程序就带着的,
家里没有示波器目前没做验证,有空会控死抓抓波形看看。
程序能用,也就没深究下去。

注意一下,到这可没玩呢,说好了要用DMA方式传输数据的,
下面才是数据传输的主要内容呢。
TIM截图20180506232023.png

TIM截图20180506230138.png

点评

謝謝分享。  详情 回复 发表于 2018-5-7 07:51


回复

使用道具 举报

1156

TA的帖子

2

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2018-5-6 22:49:25 | 显示全部楼层
本帖最后由 通宵敲代码 于 2018-5-6 23:34 编辑


定义了三个数组,主函数里写个三色循环呼吸灯看看效果。
TIM截图20180506232627.png

TIM截图20180506232619.png



附上相关程序
这个是用TIM2_CH1实现三色呼吸灯的。
STM32F1_DMA_PWM_WS2813E_2018_05_06-Bingo.zip (3.28 MB, 下载次数: 162)

点评

谢谢分享  详情 回复 发表于 2018-5-7 08:31


回复

使用道具 举报

363

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

发表于 2018-5-7 07:51:59 | 显示全部楼层
通宵敲代码 发表于 2018-5-6 22:49
上面介绍完原理,下面就是如何实现功能了,
我们直接来看程序,声明一下我们是用原子的例程移植的。
这 ...

謝謝分享。


回复

使用道具 举报

281

TA的帖子

0

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2018-5-7 08:31:00 | 显示全部楼层
通宵敲代码 发表于 2018-5-6 22:49
定义了三个数组,主函数里写个三色循环呼吸灯看看效果。






附上相关程序
这个是用TIM2_CH1实 ...

谢谢分享


回复

使用道具 举报

1156

TA的帖子

2

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2018-5-7 11:28:47 | 显示全部楼层


在开启DMA数据传输,定时器开启之前,
增加一条计数寄存器清空指令,
防止寄存器非零造成第一次脉冲信号不准确。

同时在DMA数据传输完成后,应先关闭DMA通道,再关闭定时器,
防止DMA传输完成,但PWM最后一次信号未发送完影响最后一个灯的显示。


TIM截图20180507111733.png

TIM截图20180507111130.png





回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2018-5-19 21:33:52 | 显示全部楼层
楼主,为什么我的PA0没有输出呢?用万用表也测不出来,我按照你的代码,原封不动,可就是没有输出,还请大佬指导一波


回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2018-5-19 21:37:26 | 显示全部楼层
还有,LED_Init();这个来初始化LED貌似没什么用吧,程序里好像没用上吧,输出是PA0吧?

点评

嗯,这个确实没用,以前的函数留下的。 输出引脚确实是PA0,程序都是验证过的,你好好检查一下硬件。  详情 回复 发表于 2018-5-25 17:12


回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2018-5-20 12:33:27 | 显示全部楼层
我仿真出来PA0一直是低电平


回复

使用道具 举报

1156

TA的帖子

2

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2018-5-25 17:12:02 | 显示全部楼层
eleven@ 发表于 2018-5-19 21:37
还有,LED_Init();这个来初始化LED貌似没什么用吧,程序里好像没用上吧,输出是PA0吧?

嗯,这个确实没用,以前的函数留下的。
输出引脚确实是PA0,程序都是验证过的,你好好检查一下硬件。


回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2018-7-20 10:01:28 | 显示全部楼层
楼主你的硬件不是级联?程序上看起来是每一个都用一个DMA的通道?

点评

做的四路独立控制, 需要级联你直接延长灯带就行了, 我试过288颗灯级联的,毫无压力, 官方给的数据可以级联1000颗灯  详情 回复 发表于 2018-7-30 08:58


回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2018-7-29 16:08:17 | 显示全部楼层
优酷视频打不开啊,能直接发个图片我看下或者其他视频,看下显示效果,不知道我这边显示的效果对不对。

点评

百度一搜很多这个灯珠的视频, 我这边公司的网络也上不了优酷, 我记不清这个是呼吸灯还是流水灯了, 你看一下,只要颜色渐变流畅就没问题。  详情 回复 发表于 2018-7-30 09:01


回复

使用道具 举报

1156

TA的帖子

2

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2018-7-30 08:58:59 | 显示全部楼层
DSCX05 发表于 2018-7-20 10:01
楼主你的硬件不是级联?程序上看起来是每一个都用一个DMA的通道?

做的四路独立控制,
需要级联你直接延长灯带就行了,
我试过288颗灯级联的,毫无压力,
官方给的数据可以级联1000颗灯


回复

使用道具 举报

1156

TA的帖子

2

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2018-7-30 09:01:08 | 显示全部楼层
mochou678 发表于 2018-7-29 16:08
优酷视频打不开啊,能直接发个图片我看下或者其他视频,看下显示效果,不知道我这边显示的效果对不对。

百度一搜很多这个灯珠的视频,
我这边公司的网络也上不了优酷,
我记不清这个是呼吸灯还是流水灯了,
你看一下,只要颜色渐变流畅就没问题。


回复

使用道具 举报

69

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2018-7-30 09:09:21 | 显示全部楼层


回复

使用道具 举报

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

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2018-8-21 06:56 , Processed in 0.391765 second(s), 18 queries , Gzip On, Redis On.

快速回复 返回顶部 返回列表