欢迎光临散文网 会员登陆 & 注册

讨论用一片STM32C8T6驱动2048个串行单线RGB的方法

2022-06-23 12:44 作者:萌晓宇  | 我要投稿

串行RGB WS2812 SK6812 等相信大家都很熟悉了,你电脑里面的光污染大多来源于此,网上很多相关的资料,驱动方式多种多样,PWM SPI,甚至直接进行IO模拟来驱动。

这里讨论一下,如何用一片C8T6驱动 2048个灯,并且实现以下参数:

驱动2048个RGB

30FPS 刷新速率

单片机不能阻塞

单片机不能爆空间

先看看时序,大家应该都很熟悉了。

WS2812时序

0,1这里咱们先不看,不同的灯可能会有所差异,但是一个BIT需要1.25us的时间大多数灯都一样。

那么也就是一个灯传输24个字节(R G B 各需要8位)

换算下来就是 24x1.25us = 30us/每个灯的Data Time 数据传输时间。

那么我们有2048个灯   2048x30us = 61440us 数据时间 +上RES时间50us大概一帧所需要花费时间 61.490MS 很明显 ,如果按这样 以最快的速度 刷新灯的数据也只有约16帧

所以这里咱们得把灯板拆分开来,我打样的板子是16*32,所以我就分成了4份。

灯板

这样的话 我们需要分开4个IO口同时 驱动4个单片512个灯,512*30us =15360us+50us  单片理论刷新时间应该能达到60帧多一点。但是肯定做不到这么高,这里后面再说.

确定了硬件之后我们来确定一下软件驱动。

这里我使用PWM+DMA的方式来驱动。

PWM定时器设置为800Khz周期

然后依次将对应电平的占空比放到PWM的buff数组中,就可以实现0.1的CODE输出,那么也就说 一个灯需要24个占空比值,在DMA 的BUFF中一个灯需要24个长度为16位数去储存颜色数据,(这里先不 谈RES数据)。

简单换算一下,一个灯24(PWM值)x 2(16位数据一个数据占2个字节)=48个字节。本项目2048个灯仅仅数据部分一共需要98304个字节=96K TOO BIG

众所周知C8T6拥有64KB FLASH  20K的RAM,其的身躯根本无给他这么大的BUFF空间。那么怎么办呢。

重点来了

这里我们把DMA的半传输中断和循环模式打开,实现显示缓存的功能,示意如下:

传输顺序

1,写入 BUFF1 和BUFF2启动DMA

2,进入半传输HC中断后,更新缓存1的数据(此时此刻DAM正在传输缓存2的数据)

3,进入传输完成TC中断后,更新缓存2的数据(此时此刻DAM正在传输缓存1的数据)

4,进入半传输HC中断后,更新缓存1的数据(此时此刻DAM正在传输缓存2的数据)

5,进入传输完成TC中断后,更新缓存2的数据(此时此刻DAM正在传输缓存1的数据)

............

所有灯数据传输完毕后,将DMA缓存设置为0,发送一组RES指令过去使灯数据有效。


使用这种方法可大幅节省RAM空间,如果我们缓存定义为16个灯的大小,也就是一次传输16个灯的数据,单组2个缓存就是32个灯 32*24=768长度的16位数组,也就是占用1536个字节。

由于我们分开4路PWM 同时进行驱动,一共有4组DMA缓存 也就是4*1536=6144个字节

然后用一个8位数组,存放2048个灯的RGB数据占用 6144 个字节。

6144+6144=12288个字节,对于C8T6的RAM来说也完全可以跑下去了。



下面是使用CUBEMAX工程的建立:

定时器配置

定时器配置如上


工程建立

这里我使用的是TIM1 的4个PWM通道,DMA设置为循环模式 Memory to Peripheral ,以及Half Word

时钟树如上

下面说一下程序方面需要注意的几个小点

DMA启动代码

由于分开了4组DMA,如果同时启动可能会导致同时进入传输中断导致数据错误,小小延迟一下避开同时进入中断即可解决此问题,也可以对DMA中断进行优先级进行设置来避免此问题。

TC中断数据装载
HC中断数据装载
RGB转换为PWM占空比数据的装载
装载RES数据

还有一个坑,在Cubemx生成的void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle) 代码下 通道4会有多出来的LINK

坑位

必须屏蔽其他DMA LINK。否则CH4不会进中断。

展示
展示1

展示2

以这种方式进行RGB驱动,可以大幅节约系统资源,这边测试驱动2048个RGB,还做了256 的FFT,可达到30FPS左右的帧率。

有一点不得不说,2048个2812电流爆炸,没写亮度控制的时候,通电我仿佛看到了太阳,也未敢3色全点进行测试,电源直接保护了,保守估计得有50A左右电流。

个人倒腾记录可能有不严谨的地方,请见谅,本文仅提供一种思路,涉及代码已贴出,欢迎大家一起讨论建议。

讨论用一片STM32C8T6驱动2048个串行单线RGB的方法的评论 (共 条)

分享到微博请遵守国家法律