相信大家在看到这篇文章的时候一定对WS2812芯片的时序有了一定的了解,这里对于WS2812硬件通信方面就不做过多的介绍了。驱动WS2812需要的实现纳秒级别的电平翻转,像一般主频较低的MCU很难实现这种级别的电平翻转。我在这里使用的MCU是STM32F103系列主频为72M,恰好可以通过延时翻转高低电平模拟WS2812的通信时序进而实现对WS2812灯珠的驱动。
STM32通过普通IO方式驱动WS2812灯珠首先我们要初始化IO端口。
/*** @brief 初始化IO控制口* @param * @retval None*/
void ws2811_init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //WS2811-->PA.0 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.0GPIO_ResetBits(GPIOA,GPIO_Pin_0); //PA.0 输出低电平
}
接下来便要实现合适的延时函数:
/*** @brief ws281x模块用到的延时函数* @param delay_num :延时数 (示波器测量延时时间 = delay_num * 440ns )* @retval None*/
void ws281X_delay(unsigned int delay_num)
{while(delay_num--);
}
通过示波器测量出的该延时函数的延时时间为delay_num x 440ns,恰好可以实现纳秒级别的延时。因此可用此来模拟WS281x的通信时序。
/*** @brief 根据WS281x芯片时序图编写的发送0码,1码RESET码的函数* @param * @retval None*/
void ws281x_sendLow(void) //发送0码
{PAout(0) = 1;ws281x_delay(1); //示波器测试约为440nsPAout(0) = 0;ws281x_delay(2);
}
void ws281x_sendHigh(void) //发送1码
{PAout(0) = 1;ws281x_delay(2);PAout(0) = 0;ws281x_delay(1);
}
void ws2811_Reset(void) //发送RESET码
{ PAout(0) = 0; delay_us(60); PAout(0) = 1; PAout(0) = 0;
}
接下来根据这些通信时序我们便可以实现点亮WS2812灯珠的函数了
/*** @brief 发送点亮一个灯的数据(即24bit)* @param dat:颜色的24位编码* @retval None*/
void ws281x_sendOne(uint32_t dat)
{uint8_t i;unsigned char byte;for(i = 24; i > 0; i--){byte = ((dat>>i) & 0x01); //位操作,读取dat数据的第i位if(byte == 1){ws281x_sendHigh();}else{ws281x_sendLow();}}
}
如在主函数中调用ws281x_sendOne(0XFF0000)即可点亮一个绿灯。
如果需要控制多个WS2812灯珠可以定义一个缓冲区pixelBuffer[PIXEL_NUM]的数组,首先将颜色数据依次填入缓冲区,再通过发送函数将颜色数据依次发出即可。若想实现多种炫酷效果还可以移植Adafruit_NeoPixel库函数。
本文发布于:2024-01-28 03:32:38,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17063839694480.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |