瑞薩RA0單片機連載之SPI驅動WB2812B
1 前言
WS2812B是一種數字可編程LED燈條,也被稱為NeoPixel。它由RGB(紅、綠、藍)三種顏色的LED組成,并集成了控制電路和信號處理功能。每個WS2812B LED 都有一個唯一的地址,并可以通過單個數據線進行串聯連接。
WS2812B具有以下特點:
高度可編程性:每個LED可以獨立地設置顏色和亮度,因此可以實現各種動態效果和彩色變化。
簡單的控制接口:WS2812B使用單個數據線進行通信,通過發送特定的序列來控制每個LED的顏色和亮度。
低功耗:WS2812B采用高效的LED驅動技術,具有較低的功耗,適合電池供電的應用。
靈活的應用:WS2812B可廣泛應用于室內裝飾、燈光藝術、電子產品原型設計等領域,具有豐富的創意空間和應用場景。
24bit數據結構
G7 G6 G5 G4 G3 G2 G1 G0 R7 R6 R5 R4 R3 R2 R1 R0 B7 B6 B5 B4 B3 B2 B1 B0
注:高位先發,按照GRB 的順序發送數據。
2 引腳圖
引腳功能
序號 | 符號 | 管腳名 | 功能描述 |
1 | VDD | 電源 | 供電管腳 |
2 | DOUT | 數據輸出 | 控制數據信號輸出 |
3 | VSS | 地 | 信號接地和電源接地 |
4 | DIN | 數據輸入 | 控制數據信號輸入 |
當然,在使用的過程中,我們往往會使用不止一個LED燈,會將多個燈級聯成燈帶或者燈板,我們這次使用的就是燈板。
具體級聯方式如下:
典型應用數據:外圍電路不需要加濾波電容
其中DIN作為數據的輸入端,每個LED需要24位數據控制,多出的數據會通過DOUT 引腳傳遞給下一個LED,以此類推,當WS2812 接收到280us 以上的低電平時,數據被寫入LED,燈的顏色改變。
以下是數據的表示方法:
數據傳輸時間
T0H | 0碼,高電平時間 | 220ns~380ns |
T1H | 1碼,高電平時間 | 580ns~1μs |
T0L | 0碼,低電平時間 | 580ns~1μs |
T1L | 1碼,低電平時間 | 580ns~1μs |
RES | 幀單位,低電平時間 | 280μs以上 |
時序波形圖
輸入碼型:
連接方法:
此次我采用SPI 的方式來驅動。SPI的時鐘調整為8MHz,發送一字節正好是1.25us,給ws2812 發送0即通過SPI 總線發送11000000b,發送1 即通過SPI 總線發送11111100b,非常巧妙的一種方式。
根據以上原理,我先配置SPI的stack如下:
經查看原理圖,配置SPI 的MOSI 為P101。
生成工程后,編寫代碼ws2812b.c 如下:
view plaincopy to clipboardprint?
1. #include “ws2812.h”
2.
3. static uint8_t spidate[SPIBUFL] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00,
5. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00,
6. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00,
7. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00,
8. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00,
9.
10. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8,
11. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
12. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
13.
14. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
15. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8,
16. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
17.
18. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
19. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
20. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8,
21.
22. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
23. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8,
24. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8,
25.
26. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8,
27. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
28. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8,
29.
30. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8,
31. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8,
32. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
33.
34. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8,
35. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8,
36. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8,
37.
38. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8,
39. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
40. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
41.
42. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
43. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8,
44. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
45.
46. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
47. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
48. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8,
49.
50. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
51. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8,
52. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8,
53.
54. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8,
55. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
56. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8,
57.
58. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8,
59. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8,
60. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
61.
62. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8,
63. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8,
64. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8,
65.
66. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8, 0xf8,
67. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8, 0xf8,
68. 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8, 0xf8,
69.
70. 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8, 0xf8, 0xf8,
71. 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8, 0xf8, 0xf8,
72. 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xf8, 0xf8, 0xf8
73. };
74.
75. void ws2812Init(void)
76. {
77. R_SAU_SPI_Open(&g_spi0_ctrl, &g_spi0_cfg);
78.
79. }
80.
81. void show(void)
82. {
83. R_SAU_SPI_Write(&g_spi0_ctrl, spidate,SPIBUFL, SPI_BIT_WIDTH_8_BITS);
84. R_BSP_SoftwareDelay(80, BSP_DELAY_UNITS_MICROSECONDS);
85. }
86.
87. void clear(void)
88. {
89. memset(& spidate[NUMRES], 0xc0, (NUMPIXELS) * 3 * 8);
90. }
91.
92. void setPixelColor(uint16_t n, uint8_t g, uint8_t r, uint8_t b)
93. {
94. if (n < NUMPIXELS) {
95. uint8_t *p;
96. p = &spidate[NUMRES + n * 24];
97. for(uint8_t i = 0; i < 8; i++)
98. {
99. *(p + i) = (0 == (g & (1 << (7 - i)))) ? 0xc0 : 0xf8;
100. }
101. for(uint8_t i = 0; i < 8; i++)
102. {
103. *(p + i + 8) = (0 == (r & (1 << (7 - i)))) ? 0xc0 : 0xf8;
104. }
105. for(uint8_t i = 0; i < 8; i++)
106. {
107. *(p + i + 16) = (0 == (b & (1 << (7 - i)))) ? 0xc0 :0xf8;
108. }
109. }
110. }
ws18b20c.h:
view plaincopy to clipboardprint?
1. #ifndef WS2812_H_
2. #define WS2812_H_
3. #include “hal_data.h”
4.
5. #define NUMPIXELS (8)
6. #define NUMRES (60)
7. #define SPIBUFL ((NUMPIXELS) * 3 * 8 + NUMRES)
8.
9. void ws2812Init(void);
10. void show(void);
11. void clear(void);
12. void setPixelColor(uint16_t n, uint8_t g, uint8_t r, uint8_t b);
13.
14. #endif /* WS2812_H_ */
在主函數中添加測測試代碼如下:
view plaincopy to clipboardprint?
1. void sau_spi_callback(spi_callback_args_t *p_args)
2. {
3. (void)p_args;
4. /* TODO: add your own code here */
5. }
6.
7. /*******************************************************************************************************************//**
8. * main() is generated by the RA Configuration edi tor and is used to generate threads if an RTOS is us ed. This function
9. * is called by main() when no RTOS is used.
10.**********************************************************************************************************************/
11. void hal_entry(void)
12. {
13. /* TODO: add your own code here */
14. ws2812Init();
15.
16. while(1)
17. {
18. clear();
19.
20. for(uint8_t i = 0; i < NUMPIXELS; i++)
21. {
22. setPixelColor(i, i*8+2, i*2, i*15);
23. show();
24. R_BSP_SoftwareDelay(50, BSP_DELAY_UNITS_MILLISECONDS);
25. }
26.
27. }
28.
29.
30. #if BSP_TZ_SECURE_BUILD
31. /* Enter non-secure code */
32. R_BSP_NonSecureEnter();
33. #endif
34. }
代碼的主要思路是,將寫入buff先清零,然后向數據中寫信指定個數的RGB 數據,最后刷新到spi 總線之中。
(本文來源于《EEPW》202507)
評論