WS2812E是一個集控制電路與發光電路于一體的智能外控LED光源。其外型與一個5050LED燈珠相同,每個 元件即為一個像素點。像素點內部包含了智能數字接口數據鎖存信號整形放大驅動電路,還包含有高精度的內部 振蕩器和可編程定電流控制部分,有效保證了像素點光的顏色高度一致。
一、模塊來源
模塊實物展示:
資料鏈接:https://pan.baidu.com/s/1OkCpw8ooDyuw947V0b89Rw
資料提取碼:AB12
二、規格參數
工作電壓:3.7-5.3V
工作電流:16MA
控制方式:單總線
以上信息見廠家資料文件
三、移植過程
我們的目標是將例程移植至CW32F030C8T6開發板上【能夠實現設置彩燈顏色的功能】。首先要獲取資料,查看數據手冊應如何實現讀取數據,再移植至我們的工程。
3.1查看資料
WS2812的數據協議采用單線歸零碼的通訊方式,支持串行級聯接口,能通過一根信號線完成數據的接收與解碼。每個燈就是一個像素點,每個像素點的三基色顏色可實現256級亮度顯示,完成16777216種顏色的全真色彩顯示。
像素點在上電復位以后,DIN端接受從控制器傳輸過來的數據,首先送過來的24bit數據被第一個像素點提取后,送到像素點內部的數據鎖存器,剩余的數據經過內部整形處理電路整 形放大后通過DO端口開始轉發輸出給下一個級聯的像素點,每經過一個像素點的傳輸,信號減少24bit。像素點采用自動整形轉發技術,使得該像素點的級聯個數不受信號傳送的限制,僅受限信號傳輸速度要求。
控制方式
因為使用的是單總線,一根線完成一個燈要顯示的24位顏色數據,是通過高低電平的時間長度來確定發送的是什么數據。24位的數據結構見下圖。
其中G代表三色中的綠色,R代表三色中的紅色,B表示三色中的藍色。例如想要只顯示紅色則發送 0X00FF00即可。
控制時序
發送24位顏色數據,是通過高低電平的時間長度來確定發送的是0還是1。
發送一位數據0,需要總線拉高T0H的時間再拉低T0L的時間,WS2812才會自動識別該數據是0。
發送一位數據1,需要總線拉高T1H的時間再拉低T1L的時間,WS2812才會自動識別該數據是1
3.2引腳選擇
該模塊有3個引腳,具體引腳連接見各引腳連接。
模塊接線圖
3.3移植至工程
移植步驟中的導入.c和.h文件與【CW32模塊使用】DHT11溫濕度傳感器相同,只是將.c和.h文件更改為bsp_ws2812.c與bsp_ws2812.h。這里不再過多講述,移植完成后面修改相關代碼。
在文件bsp_ws2812.c中,編寫如下代碼。
/* * Change Logs: * Date Author Notes * 2024-06-24 LCKFB-LP first version */ #include "bsp_ws2812.h" #include "stdio.h" #include "math.h" unsigned char LedsArray[WS2812_MAX * 3]; //定義顏色數據存儲數組 unsigned int ledsCount = WS2812_NUMBERS; //定義實際彩燈默認個數 unsigned int nbLedsBytes = WS2812_NUMBERS*3; //定義實際彩燈顏色數據個數 void delay_0_30us(void) { __NOP;__NOP;__NOP;__NOP;__NOP; } /****************************************************************** * 函 數 名 稱:WS2812_GPIO_Init * 函 數 說 明:對WS2812引腳初始化 * 函 數 形 參:無 * 函 數 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void WS2812_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化結構體 RCC_DIN_ENABLE(); // 使能GPIO時鐘 GPIO_InitStruct.Pins = GPIO_DIN; // GPIO引腳 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽輸出 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 輸出速度高 GPIO_Init(PORT_DIN, &GPIO_InitStruct); // 初始化 GPIO_WritePin(PORT_DIN, GPIO_DIN, GPIO_Pin_RESET); } /****************************************************************** * 函 數 名 稱:rgb_SetColor * 函 數 說 明:設置彩燈顏色 * 函 數 形 參:LedId控制的第幾個燈 color顏色數據 * 函 數 返 回:無 * 作 者:LC * 備 注:在這里我將綠和紅色進行顛倒,這樣比較符合我們日常生活的紅綠藍的順序 ******************************************************************/ void rgb_SetColor(unsigned char LedId, unsigned long color) { if( LedId > ledsCount ) { return; //to avoid overflow } LedsArray[LedId * 3] = (color>>8)&0xff; LedsArray[LedId * 3 + 1] = (color>>16)&0xff; LedsArray[LedId * 3 + 2] = (color>>0)&0xff; } /****************************************************************** * 函 數 名 稱:rgb_SetRGB * 函 數 說 明:設置彩燈顏色(三原色設置) * 函 數 形 參:LedId控制的第幾個燈 red紅色數據 green綠色數據 blue藍色數據 * 函 數 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void rgb_SetRGB(unsigned char LedId, unsigned long red, unsigned long green, unsigned long blue) { unsigned long Color=red<16|green<8|blue; rgb_SetColor(LedId,Color); } /****************************************************************** * 函 數 名 稱:rgb_SendArray * 函 數 說 明:發送彩燈數據 * 函 數 形 參:無 * 函 數 返 回:無 * 作 者:LC * 備 注:無 ******************************************************************/ void rgb_SendArray(void) { unsigned int i; //發送數據 for(i=0; i> i) )//當前位為1 { RGB_PIN_H(); delay_us(1);//0.75us RGB_PIN_L(); __NOP;__NOP;__NOP;__NOP;__NOP;//0.25us } else//當前位為0 { RGB_PIN_H(); __NOP;__NOP;__NOP;__NOP;__NOP;//0.25us RGB_PIN_L(); delay_us(1);//0.833us } } }
在文件bsp_ws2812.h中,編寫如下代碼。
/* * Change Logs: * Date Author Notes * 2024-06-24 LCKFB-LP first version */ #ifndef _BSP_WS2812_H_ #define _BSP_WS2812_H_ #include "board.h" #define RCC_DIN_ENABLE() __RCC_GPIOB_CLK_ENABLE() #define PORT_DIN CW_GPIOB #define GPIO_DIN GPIO_PIN_12 //用戶修改參數區 //#define WS2812_FREQUENCY #define RGB_PIN_L() GPIO_WritePin(PORT_DIN, GPIO_DIN, GPIO_Pin_RESET) //控制彩燈引腳(需要配置為強推挽輸出) #define RGB_PIN_H() GPIO_WritePin(PORT_DIN, GPIO_DIN, GPIO_Pin_SET) //控制彩燈引腳(需要配置為強推挽輸出) #define WS2812_MAX 8 //彩燈最大個數 #define WS2812_NUMBERS 8 //彩燈個數 #define RED 0xff0000 //紅色 #define GREEN 0x00ff00 //綠色 #define BLUE 0x0000ff //藍色 #define BLACK 0x000000 //熄滅 #define WHITE 0xffffff //白色 //8.3 -8 0.000000083 //4.16 -9 0.00000000416 void Ws2812b_WriteByte(unsigned char byte);//發送一個字節數據(@12.000MHz,理論每個機器周期83ns,測試約為76ns) void setLedCount(unsigned char count);//設置彩燈數目,范圍0-25. unsigned char getLedCount();//彩燈數目查詢函數 void rgb_SetColor(unsigned char LedId, unsigned long color);//設置彩燈顏色 void rgb_SetRGB(unsigned char LedId, unsigned long red, unsigned long green, unsigned long blue);//設置彩燈顏色 void rgb_SendArray();//發送彩燈數據 void WS2812_GPIO_Init(void); void RGB_LED_Write1(void); void RGB_LED_Reset(void); #endif
四、移植驗證
在自己工程中的main主函數中,編寫如下。
/* * Change Logs: * Date Author Notes * 2024-06-24 LCKFB-LP first version */ #include "board.h" #include "stdio.h" #include "bsp_uart.h" #include "bsp_ws2812.h" uint8_t Co = 100; unsigned int buff[]={RED,GREEN,BLUE,WHITE}; int32_t main(void) { int i = 0; board_init(); uart1_init(115200); WS2812_GPIO_Init(); printf("Start--->rn"); while(1) { for( i = 0; i < 8; i++ ) { rgb_SetColor(i,buff[i%3]); rgb_SendArray(); delay_ms(10); } delay_ms(3000); i = 0; while( Co ) { rgb_SetColor((i+0)%8,buff[0]); rgb_SetColor((i+1)%8,buff[1]); rgb_SetColor((i+2)%8,buff[2]); rgb_SetColor((i+3)%8,buff[3]); rgb_SetColor((i+4)%8,BLACK); rgb_SetColor((i+5)%8,BLACK); rgb_SetColor((i+6)%8,BLACK); rgb_SetColor((i+7)%8,BLACK); rgb_SendArray(); delay_ms(200); Co--; i++; } Co = 100; } }
移植現象:三秒前八個燈全亮,后面循環流水燈顯示。
模塊移植成功案例代碼:
鏈接:https://pan.baidu.com/s/1boqb5UkpomK2avKNqAjz-w?pwd=LCKF
提取碼:LCKF
審核編輯 黃宇
-
WS2812
+關注
關注
0文章
33瀏覽量
6554 -
CW32
+關注
關注
1文章
242瀏覽量
1105
發布評論請先 登錄
【RA4L1-SENSOR】點亮 WS2812 全彩點陣屏
【RA-Eco-RA4M2開發板評測】點亮WS2812點陣屏
WS2812B on S32K144始終閃爍白色,即使沒有數據也是如此,為什么?
代碼+案例+生態:武漢芯源半導體CW32嵌入式開發實戰正式出版

代碼+案例+生態:武漢芯源半導體CW32嵌入式開發實戰正式出版
零知開源——使用 GPIO 模擬時序驅動 WS2812B LED 燈帶

零知開源——使用 GPIO 模擬時序驅動 WS2812B LED 燈帶
零知開源——玩轉WS2812B燈條模塊

CW32模塊使用 紅外接收模塊

基于瑞薩FPB-RA4E2智能床頭燈項目——1編譯環境搭建與點亮驅動ws2812全彩LED
武漢芯源半導體CW32芯片重慶地區線下技術交流會成功舉辦
論如何使用WS2812以及類似燈珠

評論