一 背景
前段時間發(fā)現(xiàn)在驅(qū)動WS2812B燈條的時候會有突然顯示其他顏色的情況,后來排查發(fā)現(xiàn)是時序被其他任務(wù)打斷了,在控制時序的時候需要做原子性訪問來保證時序的正確性。
二 WS2812B數(shù)據(jù)手冊
2.1 邏輯0和邏輯1
2.2 發(fā)送時序
綠色數(shù)據(jù)先發(fā),高位在前
三 寫數(shù)據(jù)
3.1 精準ns和us級別延時的實現(xiàn)
一個__NOP()的時間是一個時鐘周期,如果主頻設(shè)置的是64MHz,那么一個時鐘周期就是1/64000000 = 15.625ns,這里只需要實現(xiàn)一個330ns延時,2個330ns就是660ns了。
void delay_330ns(void)
{
volatile uint8_t cnt = 21;
while(cnt--)
{
__NOP();
}
}
void delay_660ns(void)
{
volatile uint8_t cnt = 21*2;
while(cnt--)
{
__NOP();
}
}
void ws2812b_write_data(uint8_t data){
for(uint8_t i=0;i< 8;i++)
{
if(data & 0x80)//高位先發(fā)
{
GPIOA- >BSRR = GPIO_PIN_8;
delay_660ns();
GPIOA- >BRR = GPIO_PIN_8;
delay_660ns();
}
else
{
GPIOA- >BSRR = GPIO_PIN_8;
delay_330ns();
GPIOA- >BRR = GPIO_PIN_8;
delay_660ns();
}
data< <=1;
}
}
#define CONFIG_LED_COUNT 12
void updata_light(uint8_t green,uint8_t red,uint8_t blue)
{
rt_base_t level = rt_hw_interrupt_disable();//關(guān)閉中斷
for(int i=0;i< CONFIG_LED_COUNT;i++)
{
WS2812_Send(green); //發(fā)送當前需要亮的燈的顏色
WS2812_Send(red);
WS2812_Send(blue);
}
rt_hw_interrupt_enable(level);//開啟中斷
rt_hw_us_delay(300);//復(fù)位顯示
}
四 總結(jié)
當燈的數(shù)量比較多的時候,就不能用這種延時方式了,長時間的關(guān)閉中斷可能會引起一些中斷無法及時響應(yīng)造成數(shù)據(jù)丟失,在發(fā)現(xiàn)問題的時候或者調(diào)試新算法的時候,需要基于數(shù)據(jù)來分析問題,有了數(shù)據(jù)自然就會有答案了。
-
驅(qū)動器
+關(guān)注
關(guān)注
54文章
8619瀏覽量
149035 -
led燈
+關(guān)注
關(guān)注
22文章
1595瀏覽量
109335 -
GPIO
+關(guān)注
關(guān)注
16文章
1271瀏覽量
53551 -
串口中斷
+關(guān)注
關(guān)注
0文章
67瀏覽量
14237 -
WS2812B
+關(guān)注
關(guān)注
2文章
39瀏覽量
2519
發(fā)布評論請先 登錄
零知開源——使用 GPIO 模擬時序驅(qū)動 WS2812B LED 燈帶
使用ESP8266驅(qū)動WS2812B型RGB LED智能燈制作分享
怎樣使用PWM+DMA的方式去驅(qū)動WS2812B呢
用ws2812b led燈條做遠程區(qū)域面板控制器的教程
【LuckFox Pico Plus開發(fā)板免費試用】05_使用SPI驅(qū)動WS2812B
使用ESP8266驅(qū)動WS2812B型RGB LED簡單3步打造智能燈
Arduino WS2812B LED燈帶設(shè)計方案

使用WS2812b Led燈條的diy光劍控制器

迷你乒乓球含Arduino Nano WS2812B LED燈條

適用于Azure Sphere的WS2812B LED燈帶驅(qū)動器

零知開源——使用 GPIO 模擬時序驅(qū)動 WS2812B LED 燈帶

評論