中级会员
 
- 积分
- 257
- 金钱
- 257
- 注册时间
- 2014-5-12
- 在线时间
- 35 小时
|
5金钱
自己调试WS2812B遇见点小问题,困扰了很久,前来探讨下,若发现bug恳请指正!
ws2812B的驱动时序很清晰明了,我核对了好多遍,应该没问题的了,用6M波特率的SPI +DMA的方式驱动,8位模拟一位0(0xE0)或者1(0xF8)....打印的发送buff也是对的,如下:
E0 E0 E0 E0 E0 E0 E0 E0
E0 F8 F8 E0 E0 F8 E0 E0 //发送rgb为(0,0x64,0),8个灯,下面7个也同样颜色
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 F8 F8 E0 E0 F8 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 F8 F8 E0 E0 F8 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 F8 F8 E0 E0 F8 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 F8 F8 E0 E0 F8 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 F8 F8 E0 E0 F8 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 F8 F8 E0 E0 F8 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 F8 F8 E0 E0 F8 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0 //最后加上50个低电平表示reset
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 E0 E0 E0 E0 E0 E0
E0 E0 0A
以上驱动思路的实际情况是8个灯全显示的是白色,调用情况如下
printf("red...\n");
wsColorCover(100,0,0,2000);
printf("green...\n");
wsColorCover(0,100,0,2000);
printf("blue...\n");
wsColorCover(0,0,100,2000);
void ws28Show(void)
{
//wsAppendUpdate();
printf("buff: %s\n",gWs28Ctl_t.BuffSend);
if (HAL_SPI_GetState(&WS28HSPI) == HAL_SPI_STATE_READY) // SPI 空闲
{
if(HAL_SPI_Transmit_DMA(&WS28HSPI, gWs28Ctl_t.BuffSend, gWs28Ctl_t.BuffLen) == HAL_OK)
{
memset(gWs28Ctl_t.BuffSend,BIT_ZERO,sizeof(gWs28Ctl_t.BuffSend));
*(gWs28Ctl_t.BuffSend + CORLOR_LEN+ 50) = 0;
}
}
}
//发送一个颜色
void Send_8bits(uint8_t dat,uint8_t *buf)
{
uint8_t i=0;
for (i=0;i<8;i++)
{
if((dat & 0x80)==0x80)
{
*(buf+i) = BIT_ONE;
}
else
{
*(buf+i) = BIT_ZERO;
}
dat=dat<<1;
}
}
//用某颜色填充1个像素点
void Send_24bits(uint8_t RData,uint8_t GData,uint8_t BData,uint8_t *bufOneCorlor)
{
Send_8bits(GData,bufOneCorlor); //每个原色需要8个直接表示
Send_8bits(RData ,bufOneCorlor + 8);
Send_8bits(BData ,bufOneCorlor + 16);
}
//用某颜色填充所有的像素点
void wsColorCover(uint8_t r, uint8_t g, uint8_t b, uint16_t wait)
{
uint16_t i=0;
for( i=0; i<PIXEL_NUM; i++)
{
Send_24bits(r,g,b,gWs28Ctl_t.BuffSend + 24*i);//每个像素点需要24字节表示颜色
}
// gWs28Ctl_t.Status = READY;
ws28Show();
HAL_Delay(wait);
}
|
最佳答案
查看完整内容[请看2#楼]
问题找到了,全亮的原因是我给的0其实认为是1,因为我给的0的脉冲是500ns,应该再第一点就好了,我把0从发0xe0改成0xb0就可以正常驱动,不会RGB全亮...另外,发送完一段数据后,进行延时也是算作reset的(不用专门再发低电平), 因为没有给大于450ns的脉冲都会认为低电平...
以上的问题解决源于一下的一个csdn的博主, 验证的很好也很完备...值得我们学习!
plus,ws2812确实很简单给脉冲就能驱动,但是缺乏准确的datesheel,否则也不会出现 ...
|