這篇要使用到SPI+DMA,須要瞭解的話,能夠參考我另兩篇博客html
時鐘:https://www.cnblogs.com/PureHeart/p/11330967.html函數
SPI+DMA通訊:https://www.cnblogs.com/PureHeart/p/11218076.html spa
文章前半會先介紹WS2812通訊方式,文章後半纔是SPI+DMA3d
WS2812,這LED內部已經整合了信號處理的芯片,以4pin的WS2812爲例,它的引腳分別是:code
VDD:電源,3.5V~5.3Vhtm
VSS:地blog
DIN:數據輸入圖片
DOUT:數據輸出get
相關參數以下圖博客
接下來,纔是最主要的,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就是不亮
而後最最重要的地方來了
這裏的一、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