刚开始看手册,对时序要求挺严的。找了一段代码,使用PWM的,设输OC 输出比较位。会比较准。但容易乱。
后来改成延时的。
#if 0
void Din_1(void)
{
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 57);
}
void Din_0(void)
{
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 28);
}
void rst()
{
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3, 0);
//HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
HAL_Delay (1);
}
#else
// |--| | 550nS hi 1.41uS width
// | |____|
void Din_1(void)
{
HAL_GPIO_WritePin(COUT_GPIO_Port,COUT_Pin,GPIO_PIN_SET);
asm ("nop");asm ("nop");asm ("nop");asm ("nop");asm ("nop");
asm ("nop");asm ("nop");asm ("nop");asm ("nop");asm ("nop");
HAL_GPIO_WritePin(COUT_GPIO_Port,COUT_Pin,GPIO_PIN_RESET);
//asm ("nop");asm ("nop");asm ("nop");asm ("nop");asm ("nop");
}
// |--| | 408nS hi 1.3uS width
// | |____|
void Din_0(void)
{
HAL_GPIO_WritePin(COUT_GPIO_Port,COUT_Pin,GPIO_PIN_SET);
//asm ("nop");asm ("nop");asm ("nop");asm ("nop");asm ("nop");
HAL_GPIO_WritePin(COUT_GPIO_Port,COUT_Pin,GPIO_PIN_RESET);
asm ("nop");asm ("nop");asm ("nop");asm ("nop");asm ("nop");
//asm ("nop");asm ("nop");asm ("nop");asm ("nop");asm ("nop");
}
void rst()
{
HAL_GPIO_WritePin(COUT_GPIO_Port,COUT_Pin,GPIO_PIN_RESET);
}
#endif
void Send_8bits(uint8_t dat)
{
uint8_t i;
// Din_0();
for(i=0;i<8;i++)
{
if(dat & 0x80)//1,for "1",H:0.8us,L:0.45us;
{
Din_1();
}
else //0 ,for "0",H:0.4us,L: 0.85us
{
Din_0();
}
dat=dat<<1;
}
}
//G--R--B
//MSB first
void Send_2811_24bits(uint8_t GData,uint8_t RData,uint8_t BData)
{
Send_8bits(GData);
Send_8bits(RData);
Send_8bits(BData);
}
103被设置为 72M 主频工作,编译时不优化。
一个 asm ("nop") 大约耗时在 15~16nS 之间。
其实WS2812 对定时要求并不是特高。用这种NOP + 函数调用延时就能达到目的。
下面有一段测试程序,点亮12个灯,间隔半秒钟变换颜色。
for(i=0;i<12;i++)
Send_2811_24bits(255,0,0);
rst();
HAL_Delay (500);
for(i=0;i<12;i++)
Send_2811_24bits(255,255,0);
rst();
HAL_Delay (500);
for(i=0;i<12;i++)
Send_2811_24bits(0,255,0);
rst();
HAL_Delay (500);
for(i=0;i<12;i++)
Send_2811_24bits(0,255,255);
rst();
HAL_Delay (500);
for(i=0;i<12;i++)
Send_2811_24bits(0,0,255);
rst();
HAL_Delay (500);
for(i=0;i<12;i++)
Send_2811_24bits(255,0,255);
rst();
HAL_Delay (500);
for(i=0;i<12;i++)
Send_2811_24bits(255,255,255);
rst();
HAL_Delay (500);
for(i=0;i<12;i++)
Send_2811_24bits(128,128,128);
rst();
HAL_Delay (500);