什么是WS2812B?
WS2812B是一款全彩LED控制IC,單總線(xiàn)控制,何為單總線(xiàn)我的理解就是數(shù)據(jù)線(xiàn)在一根線(xiàn)上傳輸?shù)目刂品绞骄褪菃慰偩€(xiàn)。其實(shí)要把燈點(diǎn)亮僅有一根線(xiàn)是不行的,還需要電源線(xiàn)和地線(xiàn)給其供電。
WS2812B燈帶是怎么連接的呢?
就是一顆燈珠串聯(lián)另外一個(gè)燈珠,信號(hào)通過(guò)一根數(shù)據(jù)線(xiàn)相連起來(lái)控制等的亮滅就是在這根信號(hào)線(xiàn)上發(fā)送數(shù)據(jù)。
WS2812B燈帶的數(shù)據(jù)是什么樣的呢?
在說(shuō)數(shù)據(jù)格式之前先來(lái)補(bǔ)充一下關(guān)于色彩的知識(shí)點(diǎn),就是三原色,紅綠藍(lán),也就是我們常說(shuō)的RGB,R就是RED,G就是GREEN,B就是BLUE,一個(gè)彩色可以用這三種顏色的比例來(lái)混合出來(lái)。
為什么是紅綠藍(lán)?
三原色的原理不是出于物理原因,而是由于生理原因造成的。人的眼睛內(nèi)有幾種辨別顏色的錐形感光細(xì)胞,到的刺激略大于辨別綠色的細(xì)胞,人的感覺(jué)是黃色;如果辨別黃綠色的細(xì)胞受到的刺激大大高于辨別綠色的細(xì)胞,人的感覺(jué)是紅色。雖然三種細(xì)胞并不是分別對(duì)紅色、綠色和藍(lán)色最敏感,但這三種光可以分別對(duì)三種錐形細(xì)胞產(chǎn)生刺激。
既然“三原色的原理不是出于物理原因,而是由于生理原因造成的”,那么前段所說(shuō)的“用三種原色的光以不同的比例加合到一起,形成各種顏色的光”顯然就不大合適。使用三原色并不足以重現(xiàn)所有的色彩,準(zhǔn)確的說(shuō)法應(yīng)該是“將三原色光以不同的比例復(fù)合后,對(duì)人的眼睛可以形成與各種頻率的可見(jiàn)光等效的色覺(jué)?!敝挥心切┰谌纳人x的顏色三角內(nèi)的顏色,才可以利用三原色的光以非負(fù)量相加混合得到。
例如,紅光與綠光按某種比例復(fù)合,對(duì)三種錐狀細(xì)胞刺激后產(chǎn)生的色覺(jué)可與眼睛對(duì)單純的黃光的色覺(jué)等效。但絕不能認(rèn)為紅光與綠光按某種比例復(fù)合后生成黃光,或黃光是由紅光和綠光復(fù)合而成的。
24bit數(shù)據(jù)如何構(gòu)造?
既然是24bit數(shù)據(jù)代表三種顏色,我們就要首先知道一個(gè)bit的意義是什么,我們傳統(tǒng)意義上來(lái)說(shuō)1個(gè)bit代表一個(gè)數(shù)據(jù)位,但是對(duì)于數(shù)據(jù)位bit的理解好像就是“1”或者“0”在數(shù)電里我們很容易把高低電平跟邏輯1和邏輯0對(duì)應(yīng)起來(lái),但是表示燈珠的邏輯電平不是簡(jiǎn)單的高低電平。
在數(shù)值上0xFFFFFF就是24bit的1,0x000000就是24bit的0.這里有8個(gè)bit代表顏色G分量,G7G6G5G4G3G2G1G0,有8個(gè)bit代表R分量R7R6R5R4R3R2R1R0,有8個(gè)bit代表B分量B7B6B5B4B3B2B1B0,當(dāng)不同分量組合時(shí)候就會(huì)有不同的數(shù)據(jù)產(chǎn)生,這個(gè)數(shù)據(jù)背后其實(shí)是邏輯電平,這里要說(shuō)明的是彩燈的邏輯“1”并不是簡(jiǎn)簡(jiǎn)單單的高電平,彩燈的邏輯“0”也不是簡(jiǎn)簡(jiǎn)單單的低電平。
WS2812B的邏輯“1”和邏輯“0”
由上圖可知“0”碼和“1”碼都是既有高電平又有低電平不過(guò)高電平和低電平的比例不同,這點(diǎn)很好理解,重點(diǎn)是分析一下它的特點(diǎn),首先直觀的特點(diǎn)就是編碼“0”的電平高電平時(shí)間短一些低電平時(shí)間長(zhǎng)一些,這也恰好符合我們的邏輯畢竟它還是低電平多一些的,編碼“1”的電平高電平時(shí)間就長(zhǎng)一些,而低電平就短一些。
但是不管是高電平還是低電平他們占用整個(gè)時(shí)間長(zhǎng)度是一樣的,這里還有一個(gè)很長(zhǎng)的低電平這個(gè)代表復(fù)位信號(hào)。
WS2812B控制波形的精準(zhǔn)描述如何?
這里涉及到嚴(yán)格的數(shù)學(xué)描述了,長(zhǎng)一點(diǎn)是多長(zhǎng)?短一點(diǎn)是多短?這個(gè)肯定是有標(biāo)準(zhǔn)或者是約束的
理論上來(lái)說(shuō),高電平時(shí)長(zhǎng)和低電平時(shí)長(zhǎng)加起來(lái)應(yīng)該是0.4us+0.85us或者0.85us+0.4us也就是說(shuō)總共要占用1.25us的時(shí)間才可以編碼出來(lái)一個(gè)“0”或者“1”出來(lái)。復(fù)位是要求50us以上,顯然是要比編碼的0或者1占用的時(shí)間要多的。
當(dāng)然既然是電路的高低電平時(shí)長(zhǎng)就會(huì)引入誤差這個(gè)在誤差允許的范圍內(nèi)我們可以接受,這個(gè)范圍就是上下不超過(guò)150ns這里是ns比us還要小的時(shí)間,這個(gè)其實(shí)時(shí)間要求還是很?chē)?yán)格的。
如何編程實(shí)現(xiàn)?
這里我選用我手上一個(gè)正點(diǎn)原子開(kāi)發(fā)板,網(wǎng)上基于這種方式有很多驅(qū)動(dòng)方案,有直接驅(qū)動(dòng)也有PWM驅(qū)動(dòng)也有SPI驅(qū)動(dòng),還有PWM+DMA驅(qū)動(dòng),還有用一些開(kāi)源庫(kù)進(jìn)行驅(qū)動(dòng)的,我感覺(jué)各種驅(qū)動(dòng)方式各有優(yōu)缺點(diǎn),我先來(lái)嘗試我認(rèn)為最容易想到的方式(不一定是最好的或者最合適的)玩一下,后面會(huì)根據(jù)這些方式的特點(diǎn)進(jìn)行一個(gè)總結(jié),在相對(duì)應(yīng)的需求下選用合適的方案是我們應(yīng)該重點(diǎn)考慮的。
實(shí)現(xiàn)us級(jí)別延時(shí)
硬件延時(shí)NOP實(shí)現(xiàn)
滴答定時(shí)器中斷實(shí)現(xiàn)
普通定時(shí)器實(shí)現(xiàn)
先用nop實(shí)現(xiàn)個(gè)us延時(shí)我手上的板子是精英板主控芯片是STM32F103ZET6系統(tǒng)頻率是72M,一個(gè)NOP的周期就是1/72M單位是s = 1/72=單位是us,換句話(huà)說(shuō)也就是72個(gè)NOP浪費(fèi)的時(shí)間是1us,0.4us就是0.4*72=28.8個(gè)NOP取整數(shù)29,0.2個(gè)NOP的誤差,因?yàn)橐粋€(gè)NOP是1/72 1000 個(gè)約等于是13.88個(gè)ns 所以0.2個(gè)NOP引起的誤差在150ns以?xún)?nèi)可以接受。
0.8572=61.2NOP同樣取整數(shù)61個(gè)NOP,這樣組合一下編碼0的波形和編碼1的波形就有了,實(shí)現(xiàn)一個(gè) us函數(shù) 50us的低電平也可以產(chǎn)生復(fù)位信號(hào),理論分析完畢咱直接上代碼測(cè)試。
void RGB_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PA,PD端口時(shí)鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //LED0-- >PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根據(jù)設(shè)定參數(shù)初始化GPIOA.8
GPIO_ResetBits(GPIOB,GPIO_Pin_12); //PD.2 輸出高
}
void Bit_0(void)
{
GPIO_SetBits(GPIOB,GPIO_Pin_12); //PB12 輸出高
Delay_L();
GPIO_ResetBits(GPIOB,GPIO_Pin_12); //PB12 輸出高
Delay_H();
}
void Bit_1(void)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_12); //PB12 輸出高
Delay_H();
GPIO_SetBits(GPIOB,GPIO_Pin_12); //PB12 輸出高
Delay_L();
}
void RGB_Set(void)
{
for(uint8_t i = 0;i< 8;i++)
{
Bit_1();
}
for(uint8_t i = 0;i< 8;i++)
{
Bit_0();
}
for(uint8_t i = 0;i< 8;i++)
{
Bit_1();
}
// for(uint8_t i = 0;i< 24;i++)
// {
// delay_us(100);
// }
}
void Delay_L(void)
{
__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();
}
void Delay_H(void)
{
__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();__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();
}
-
LED控制
+關(guān)注
關(guān)注
0文章
39瀏覽量
16948 -
RGB
+關(guān)注
關(guān)注
4文章
799瀏覽量
58569 -
定時(shí)器中斷
+關(guān)注
關(guān)注
0文章
49瀏覽量
11232 -
PWM驅(qū)動(dòng)
+關(guān)注
關(guān)注
0文章
28瀏覽量
1224 -
WS2812B
+關(guān)注
關(guān)注
1文章
38瀏覽量
2196
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論