一、WS2812介紹
WS2812是一種廣泛使用的地址可控制的RGB LED模塊,其內(nèi)置驅(qū)動(dòng)電路和控制芯片,允許用戶通過單線信號(hào)控制多個(gè)LED的顏色和亮度。以下是WS2812模塊的一些主要特點(diǎn)和應(yīng)用:
主要特點(diǎn)
單線控制: WS2812模塊通過單一數(shù)據(jù)線進(jìn)行控制,簡(jiǎn)化了連接線的復(fù)雜度。
地址可控: 每個(gè)WS2812 LED都有獨(dú)立的地址,這意味著你可以分別控制每個(gè)LED的顏色和亮度,適合制作動(dòng)態(tài)效果。
多彩顯示: 支持全彩顯示,通??梢曰旌霞t色、綠色和藍(lán)色三基色,產(chǎn)生多種顏色。
鏈?zhǔn)竭B接: 支持多顆WS2812 LED串聯(lián),可以方便地?cái)U(kuò)展LED的數(shù)量,只需將下一顆LED的數(shù)據(jù)線連接到前一顆LED上。
高亮度和高密度: WS2812 LED具有較高的亮度,可以在較大面積上提供均勻的光效,適合室內(nèi)外裝飾和顯示。
控制精度: 通常提供256級(jí)亮度(8位)和1670萬種顏色選擇,確保豐富的視覺效果。
主控制板上的WS2812部分如下圖:

原理圖
主控制板上WS2812模塊的接線圖如下:

可以看到一共有八個(gè)模塊級(jí)聯(lián)在一起,并且由PA12控制。
通信原理
WS2812的數(shù)據(jù)協(xié)議采用單線歸零碼的通訊方式,支持串行級(jí)聯(lián)接口,能通過一根信號(hào)線完成數(shù)據(jù)的接收與解碼。每個(gè)燈就是一個(gè)像素點(diǎn),每個(gè)像素點(diǎn)的三基色顏色可實(shí)現(xiàn)256級(jí)亮度顯示,完成16777216種顏色的全真色彩顯示。
像素點(diǎn)在上電復(fù)位以后,DIN端接受從控制器傳輸過來的數(shù)據(jù),首先送過來的24bit數(shù)據(jù)被第一個(gè)像素點(diǎn)提取后,送到像素點(diǎn)內(nèi)部的數(shù)據(jù)鎖存器,剩余的數(shù)據(jù)經(jīng)過內(nèi)部整形處理電路整 形放大后通過DO端口開始轉(zhuǎn)發(fā)輸出給下一個(gè)級(jí)聯(lián)的像素點(diǎn),每經(jīng)過一個(gè)像素點(diǎn)的傳輸,信號(hào)減少24bit。像素點(diǎn)采用自動(dòng)整形轉(zhuǎn)發(fā)技術(shù),使得該像素點(diǎn)的級(jí)聯(lián)個(gè)數(shù)不受信號(hào)傳送的限制,僅受限信號(hào)傳輸速度要求。
控制方式
因?yàn)槭褂玫氖菃慰偩€,一根線完成一個(gè)燈要顯示的24位顏色數(shù)據(jù),是通過高低電平的時(shí)間長度來確定發(fā)送的是什么數(shù)據(jù)。24位的數(shù)據(jù)結(jié)構(gòu)見下圖。

其中G代表三色中的綠色,R代表三色中的紅色,B表示三色中的藍(lán)色。例如想要只顯示紅色則發(fā)送 0X00FF00即可。
控制時(shí)序
發(fā)送24位顏色數(shù)據(jù),是通過高低電平的時(shí)間長度來確定發(fā)送的是0還是1。

發(fā)送一位數(shù)據(jù)0,需要總線拉高T0H的時(shí)間再拉低T0L的時(shí)間,WS2812才會(huì)自動(dòng)識(shí)別該數(shù)據(jù)是0。
發(fā)送一位數(shù)據(jù)1,需要總線拉高T1H的時(shí)間再拉低T1L的時(shí)間,WS2812才會(huì)自動(dòng)識(shí)別該數(shù)據(jù)是1。
二、驅(qū)動(dòng)代碼編寫
WS2812的驅(qū)動(dòng)方法有很多種,定時(shí)器+DMA,SPI+DMA,軟件模擬等,我們這里選擇軟件模擬時(shí)序的方式來驅(qū)動(dòng)。
首先初始化GPIO口,將PA12口配置為推挽輸出。注意CW32F030和CW32L012的時(shí)鐘配置區(qū)別。
void WS2812_Init(void)
{
__RCC_GPIOA_CLK_ENABLE();//開啟時(shí)鐘
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.IT=GPIO_IT_NONE;
GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;//推挽輸出
GPIO_InitStruct.Pins=GPIO_PIN_12;
GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
GPIO_Init(CW_GPIOA, &GPIO_InitStruct);
RGB_Color_Init();//初始化所有燈
}
隨后根據(jù)時(shí)序的高低電平要求,先編寫一個(gè)ns延時(shí),由于當(dāng)前使用主頻為64mhz,可以算出一個(gè)機(jī)器指令所需時(shí)間大概為1/64=15ns,然后加上GPIO電平翻轉(zhuǎn)時(shí)間即可。
/**************************
400ns延時(shí)
**************************/
void delay_400ns(void)//409
{
__nop();__nop();__nop();__nop();__nop();//__nop();__nop();
}
/**************************
800ns延時(shí)
**************************/
void delay_800ns(void)//800
{
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
// __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
// __nop();__nop();
}
然后根據(jù)時(shí)序所需的高低電平時(shí)間編寫0,1指令
/**************************
發(fā)送1
**************************/
void RGB_Send1(void)
{
RGB_H;
delay_800ns();
RGB_L;
delay_400ns();
}
/**************************
發(fā)送0
**************************/
void RGB_Send0(void)
{
RGB_H;
delay_400ns();
RGB_L;
delay_800ns();
}
然后就可以向芯片發(fā)送指令了,一個(gè)顏色分為RGB三個(gè)色域,一個(gè)色域?yàn)?位,所以我們需要八位數(shù)據(jù)一起發(fā)送,編寫如下代碼:
/**************************
發(fā)送顏色數(shù)據(jù),高位先行
**************************/
void RGB_send_Data(uint8_t Data)
{
uint8_t i;
for(i=0;i8;i++)
{
if(Data & 0x80)
{
RGB_Send1();
}
else
{
RGB_Send0();
}
Data<=1;
}
}
這樣就可以向芯片發(fā)送指定的顏色數(shù)據(jù)啦,最后在封裝一下,我們想要的要求是指定某個(gè)燈亮某種顏色,或者指定某個(gè)燈熄滅,不能影響到其他燈,所以我們定義一個(gè)數(shù)組來裝下所有燈的顏色數(shù)據(jù),到時(shí)候只需要改變數(shù)組中固定位置的值就可以直接改變顏色了,代碼如下:
/**************************
顯示顏色
n:第幾個(gè)燈
R:紅色
G:綠色
B:藍(lán)色
**************************/
void Send_RGB(uint8_t n,uint8_t R,uint8_t G,uint8_t B)
{
uint8_t i;
RGB_Data[3*n-3]=G;
RGB_Data[3*n-2]=R;
RGB_Data[3*n-1]=B;
for(i=0;i24;i++)
{
RGB_send_Data(RGB_Data[i]);
}
RGB_Reset();
}
最后在main函數(shù)編寫如下代碼(OLED顯示代碼不在此處列出)
int main(void)
{
OLED_Init();//初始化
OLED_ShowString(1,1,"Hello");//OLED顯示字符串
WS2812_Init();
while(1)
{
Send_RGB(1,255,0,0);//255,0,0對(duì)應(yīng)紅色
Delay_ms(500);
Send_RGB(1,0,255,0);//255,0,0對(duì)應(yīng)綠色
Delay_ms(500);
Send_RGB(1,0,0,255);//255,0,0對(duì)應(yīng)藍(lán)色
Delay_ms(500);
}
}
三、工作現(xiàn)象
在燒寫代碼之后,我們可以觀察到以下現(xiàn)象,OLED第一行第一列顯示HELLO,第一個(gè)RGB燈每隔500ms轉(zhuǎn)換一次顏色,在紅綠藍(lán)三色之間反復(fù)切換。

-
led
+關(guān)注
關(guān)注
243文章
24612瀏覽量
691030 -
RGB
+關(guān)注
關(guān)注
4文章
831瀏覽量
61989 -
驅(qū)動(dòng)電路
+關(guān)注
關(guān)注
158文章
1622瀏覽量
111687 -
智能小車
+關(guān)注
關(guān)注
87文章
560瀏覽量
83440
發(fā)布評(píng)論請(qǐng)先 登錄
CW32L012/F030靈眸X1智能小車——超聲波模塊配置
STM32F030 MDA+PWM驅(qū)動(dòng)ws2812b,起始的50US的低電平是怎么產(chǎn)生?
【RA4L1-SENSOR】點(diǎn)亮 WS2812 全彩點(diǎn)陣屏
**CW32L012****開發(fā)評(píng)估板的第一個(gè)程序**
CW32L012小型機(jī)器人控制評(píng)估板活動(dòng) 四足機(jī)器人+智能小車 開箱評(píng)測(cè)
使用DMA+PWM方式驅(qū)動(dòng)ws2812
Arduino控制WS2812燈帶的方法
STM32F103C8T6+PWM+DMA驅(qū)動(dòng)WS2812燈帶的方法
WS2812驅(qū)動(dòng)的總結(jié)和時(shí)序的詳細(xì)資料分析
STM32使用LL庫PWM的DMA模式驅(qū)動(dòng)ws2812
STM32F103C8T6+PWM+DMA驅(qū)動(dòng) WS2812燈帶
PWM+DMA 驅(qū)動(dòng) WS2812
如何使用智能手機(jī)控制16x16 WS2812 Led矩陣
CW32L012與STM32F103的三角運(yùn)算性能對(duì)比
CW32L012/F030靈眸X1智能小車——板載WS2812驅(qū)動(dòng)示例
評(píng)論