一 背景
前段時間發(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ù)自然就會有答案了。
-
驅動器
+關注
關注
53文章
8256瀏覽量
146591 -
led燈
+關注
關注
22文章
1592瀏覽量
108108 -
GPIO
+關注
關注
16文章
1206瀏覽量
52173 -
串口中斷
+關注
關注
0文章
67瀏覽量
13935 -
WS2812B
+關注
關注
1文章
38瀏覽量
2196
發(fā)布評論請先 登錄
相關推薦
評論