討論用一片STM32C8T6驅(qū)動2048個串行單線RGB的方法

串行RGB WS2812 SK6812 等相信大家都很熟悉了,你電腦里面的光污染大多來源于此,網(wǎng)上很多相關(guān)的資料,驅(qū)動方式多種多樣,PWM SPI,甚至直接進行IO模擬來驅(qū)動。

這里討論一下,如何用一片C8T6驅(qū)動 2048個燈,并且實現(xiàn)以下參數(shù):
驅(qū)動2048個RGB
30FPS 刷新速率
單片機不能阻塞
單片機不能爆空間
先看看時序,大家應該都很熟悉了。

0,1這里咱們先不看,不同的燈可能會有所差異,但是一個BIT需要1.25us的時間大多數(shù)燈都一樣。
那么也就是一個燈傳輸24個字節(jié)(R G B 各需要8位)
換算下來就是 24x1.25us = 30us/每個燈的Data Time 數(shù)據(jù)傳輸時間。
那么我們有2048個燈?? 2048x30us = 61440us 數(shù)據(jù)時間 +上RES時間50us大概一幀所需要花費時間 61.490MS 很明顯 ,如果按這樣 以最快的速度 刷新燈的數(shù)據(jù)也只有約16幀
所以這里咱們得把燈板拆分開來,我打樣的板子是16*32,所以我就分成了4份。

這樣的話 我們需要分開4個IO口同時 驅(qū)動4個單片512個燈,512*30us =15360us+50us? 單片理論刷新時間應該能達到60幀多一點。但是肯定做不到這么高,這里后面再說.

確定了硬件之后我們來確定一下軟件驅(qū)動。
這里我使用PWM+DMA的方式來驅(qū)動。
PWM定時器設置為800Khz周期
然后依次將對應電平的占空比放到PWM的buff數(shù)組中,就可以實現(xiàn)0.1的CODE輸出,那么也就說 一個燈需要24個占空比值,在DMA 的BUFF中一個燈需要24個長度為16位數(shù)去儲存顏色數(shù)據(jù),(這里先不 談RES數(shù)據(jù))。
簡單換算一下,一個燈24(PWM值)x 2(16位數(shù)據(jù)一個數(shù)據(jù)占2個字節(jié))=48個字節(jié)。本項目2048個燈僅僅數(shù)據(jù)部分一共需要98304個字節(jié)=96K TOO BIG
眾所周知C8T6擁有64KB FLASH? 20K的RAM,其的身軀根本無給他這么大的BUFF空間。那么怎么辦呢。
重點來了
這里我們把DMA的半傳輸中斷和循環(huán)模式打開,實現(xiàn)顯示緩存的功能,示意如下:

1,寫入 BUFF1 和BUFF2啟動DMA
2,進入半傳輸HC中斷后,更新緩存1的數(shù)據(jù)(此時此刻DAM正在傳輸緩存2的數(shù)據(jù))
3,進入傳輸完成TC中斷后,更新緩存2的數(shù)據(jù)(此時此刻DAM正在傳輸緩存1的數(shù)據(jù))
4,進入半傳輸HC中斷后,更新緩存1的數(shù)據(jù)(此時此刻DAM正在傳輸緩存2的數(shù)據(jù))
5,進入傳輸完成TC中斷后,更新緩存2的數(shù)據(jù)(此時此刻DAM正在傳輸緩存1的數(shù)據(jù))
............
所有燈數(shù)據(jù)傳輸完畢后,將DMA緩存設置為0,發(fā)送一組RES指令過去使燈數(shù)據(jù)有效。
使用這種方法可大幅節(jié)省RAM空間,如果我們緩存定義為16個燈的大小,也就是一次傳輸16個燈的數(shù)據(jù),單組2個緩存就是32個燈 32*24=768長度的16位數(shù)組,也就是占用1536個字節(jié)。
由于我們分開4路PWM 同時進行驅(qū)動,一共有4組DMA緩存 也就是4*1536=6144個字節(jié)
然后用一個8位數(shù)組,存放2048個燈的RGB數(shù)據(jù)占用 6144 個字節(jié)。
6144+6144=12288個字節(jié),對于C8T6的RAM來說也完全可以跑下去了。

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

定時器配置如上

這里我使用的是TIM1 的4個PWM通道,DMA設置為循環(huán)模式 Memory to Peripheral ,以及Half Word

時鐘樹如上

下面說一下程序方面需要注意的幾個小點

由于分開了4組DMA,如果同時啟動可能會導致同時進入傳輸中斷導致數(shù)據(jù)錯誤,小小延遲一下避開同時進入中斷即可解決此問題,也可以對DMA中斷進行優(yōu)先級進行設置來避免此問題。




還有一個坑,在Cubemx生成的void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle) 代碼下 通道4會有多出來的LINK

必須屏蔽其他DMA LINK。否則CH4不會進中斷。




展示2
以這種方式進行RGB驅(qū)動,可以大幅節(jié)約系統(tǒng)資源,這邊測試驅(qū)動2048個RGB,還做了256 的FFT,可達到30FPS左右的幀率。
有一點不得不說,2048個2812電流爆炸,沒寫亮度控制的時候,通電我仿佛看到了太陽,也未敢3色全點進行測試,電源直接保護了,保守估計得有50A左右電流。
個人倒騰記錄可能有不嚴謹?shù)牡胤剑堃娬?,本文僅提供一種思路,涉及代碼已貼出,歡迎大家一起討論建議。