【STM32】WS2812介紹、使用SPI+DMA發送數據


這篇要使用到SPI+DMA,需要了解的話,可以參考我另兩篇博客

時鍾:https://www.cnblogs.com/PureHeart/p/11330967.html

SPI+DMA通信:https://www.cnblogs.com/PureHeart/p/11218076.html 

 

文章前半會先介紹WS2812通信方式,文章后半才是SPI+DMA

 

WS2812,這LED內部已經整合了信號處理的芯片,以4pin的WS2812為例,它的引腳分別是:

VDD:電源,3.5V~5.3V

VSS:地

DIN:數據輸入

DOUT:數據輸出

相關參數如下圖

 

接下來,才是最主要的,WS2812是如何通信?

它就像一塊大蛋糕

把大蛋糕交給第1人,第1人吃了一口

然后把吃過的大蛋糕,交給第2人,第2人吃了一口

再然后把吃過的大蛋糕,交給第3人,第3人吃了一口....

數據也是如此,例如上圖,以24bit為1組數據,相當於蛋糕的一口

D1(第一顆LED)收到3組數據(大蛋糕,3×24bit),自己截取一組數據(吃一口,24bit),剩下兩組數據(2×24bit),交給D2

D2也截取一組,剩下最后一組,交給D3

D3也一定要截取,然后就沒有數據能交給D4了(假設如圖那樣,只發了3組數據)

那什么時候,WS2812會認為你的數據是新的呢(新一輪的蛋糕)?

低電平時間 >= 50us,WS2812就會認為是新一輪的數據了

至於為什么是低電平,下面的圖片,我會和24bit的內容一起介紹

24bit的數據里面,最高8位是控制綠色,中間8位控制紅色,低8位控制藍色

亮度為0~255,所以1111 1111就是最亮,0000 0000就是不亮

然后最最重要的地方來了

這里的1、0,上圖說的很明白了

一定時間的高電平 + 一定時間的低電平 = WS2812承認的一位信號(高電平或低電平)

0 code(WS2812承認的低電平)就要求【T0H】和【T0L】的時間,當然 1 code(高電平)也是

所以!

假設以串口為例(用串口比喻,是因為我覺得大家應該都熟悉,當然,這里還沒考慮WS2812需要很高波特率這個問題)

設置好串口初始化之類的,然后對照g7,g6,g5,...,b0,調用串口發送3個字節來點亮1個WS2812,這是不可能的

如下圖所示

既然此路不通,那應該如何解決呢?

我們應該進行壓縮,如下圖

是不是啊,只要我把一個字節的長度(以綠色波形為例),壓縮到跟G7一樣的長度(圖片只壓縮到G7~G3,弄的太小就看不清楚啦)

然后再改一下,不要發0x90,按照【T0H、T0L】【T1H、T1L】,就能控制了

所以,要能控制WS2812,我必須要發24個字節,這還只是一個LED要的數據而已

然后是壓縮,有經驗的人應該馬上會想到,其實這就是時鍾,設定好SPI的時鍾,就能達到這樣的效果

 

那么時鍾應該要設置多少呢?

在STM32F4里面,SPI發送可以設置8位或是16位數據

8位為例,8位的時間總和,不管是 0 code 還是 1 code ,都約等於1.25u

1.25u / 8,每一位等於0.15625u

公式:頻率 = 周期的倒數

頻率 = 1 / 0.15625u

頻率 = 6.4M

SPI設置6.4M就可以了

當然,我上面用的是1.25u,也可以用1.1u,也可以用1.4u(因為有150n的允許誤差)

反正不超過規定的值,就可以了。。。也許。。。?

主時鍾設置為40M,SPI經過8分頻,得到5M

因為我有一些其他外設要配合,才這么設置主時鍾的

當然,我實測5M也是可以的。。。

1 / 5M = 0.2u

0.2u × 8 = 1.6u,已經超過規定的1.25u ± 150n 了!

不過可以用就好了。。。

 

代碼,應該也沒有什么好講的了,還是把它貼上吧,另外我有用DMA(減少CPU負擔)

下圖main函數里while(1)里面的0805LED,只是普通的LED,和WS2812沒關系,啊,另外,我用的是STM32F4的芯片

代碼鏈接:https://pan.baidu.com/s/1S33m7tx9Tfg8e3WKphGuNQ

提取碼:s82g

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM