一 背景
前段時間發(fā)現(xiàn)在驅動WS2812B燈條的時候會有突然顯示其他顏色的情況,后來排查發(fā)現(xiàn)是時序被其他任務打斷了,在控制時序的時候需要做原子性訪問來保證時序的正確性。
二 WS2812B數(shù)據(jù)手冊
2.1 邏輯0和邏輯1
2.2 發(fā)送時序
綠色數(shù)據(jù)先發(fā),高位在前
三 寫數(shù)據(jù)
3.1 精準ns和us級別延時的實現(xiàn)
一個__NOP()的時間是一個時鐘周期,如果主頻設置的是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();//關閉中斷
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);//復位顯示
}
四 總結
當燈的數(shù)量比較多的時候,就不能用這種延時方式了,長時間的關閉中斷可能會引起一些中斷無法及時響應造成數(shù)據(jù)丟失,在發(fā)現(xiàn)問題的時候或者調試新算法的時候,需要基于數(shù)據(jù)來分析問題,有了數(shù)據(jù)自然就會有答案了。
-
驅動器
+關注
關注
54文章
8481瀏覽量
148576 -
led燈
+關注
關注
22文章
1593瀏覽量
109170 -
GPIO
+關注
關注
16文章
1238瀏覽量
53310 -
串口中斷
+關注
關注
0文章
67瀏覽量
14188 -
WS2812B
+關注
關注
2文章
39瀏覽量
2494
發(fā)布評論請先 登錄
相關推薦
零知開源——使用 GPIO 模擬時序驅動 WS2812B LED 燈帶
使用ESP8266驅動WS2812B型RGB LED智能燈制作分享
怎樣使用PWM+DMA的方式去驅動WS2812B呢
用ws2812b led燈條做遠程區(qū)域面板控制器的教程
【LuckFox Pico Plus開發(fā)板免費試用】05_使用SPI驅動WS2812B
Arduino WS2812B LED燈帶設計方案

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

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

適用于Azure Sphere的WS2812B LED燈帶驅動器

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

評論