CW32L012/F030灵眸X1智能小车——板载WS2812驱动示例

描述

一、WS2812介绍

WS2812是一种广泛使用的地址可控制的RGB LED模块,其内置驱动电路和控制芯片,允许用户通过单线信号控制多个LED的颜色和亮度。以下是WS2812模块的一些主要特点和应用:

主要特点

单线控制: WS2812模块通过单一数据线进行控制,简化了连接线的复杂度。

地址可控: 每个WS2812 LED都有独立的地址,这意味着你可以分别控制每个LED的颜色和亮度,适合制作动态效果。

多彩显示: 支持全彩显示,通常可以混合红色、绿色和蓝色三基色,产生多种颜色。

链式连接: 支持多颗WS2812 LED串联,可以方便地扩展LED的数量,只需将下一颗LED的数据线连接到前一颗LED上。

高亮度和高密度: WS2812 LED具有较高的亮度,可以在较大面积上提供均匀的光效,适合室内外装饰和显示。

控制精度: 通常提供256级亮度(8位)和1670万种颜色选择,确保丰富的视觉效果。

主控制板上的WS2812部分如下图:

智能小车

原理图

主控制板上WS2812模块的接线图如下:

智能小车

可以看到一共有八个模块级联在一起,并且由PA12控制。

通信原理

WS2812的数据协议采用单线归零码的通讯方式,支持串行级联接口,能通过一根信号线完成数据的接收与解码。每个灯就是一个像素点,每个像素点的三基色颜色可实现256级亮度显示,完成16777216种颜色的全真色彩显示。

像素点在上电复位以后,DIN端接受从控制器传输过来的数据,首先送过来的24bit数据被第一个像素点提取后,送到像素点内部的数据锁存器,剩余的数据经过内部整形处理电路整 形放大后通过DO端口开始转发输出给下一个级联的像素点,每经过一个像素点的传输,信号减少24bit。像素点采用自动整形转发技术,使得该像素点的级联个数不受信号传送的限制,仅受限信号传输速度要求。

控制方式

因为使用的是单总线,一根线完成一个灯要显示的24位颜色数据,是通过高低电平的时间长度来确定发送的是什么数据。24位的数据结构见下图。

智能小车

其中G代表三色中的绿色,R代表三色中的红色,B表示三色中的蓝色。例如想要只显示红色则发送 0X00FF00即可。

控制时序

发送24位颜色数据,是通过高低电平的时间长度来确定发送的是0还是1。

智能小车

发送一位数据0,需要总线拉高T0H的时间再拉低T0L的时间,WS2812才会自动识别该数据是0。

发送一位数据1,需要总线拉高T1H的时间再拉低T1L的时间,WS2812才会自动识别该数据是1。

二、驱动代码编写

WS2812的驱动方法有很多种,定时器+DMA,SPI+DMA,软件模拟等,我们这里选择软件模拟时序的方式来驱动。

首先初始化GPIO口,将PA12口配置为推挽输出。注意CW32F030和CW32L012的时钟配置区别。

 

void WS2812_Init(void)
{
        __RCC_GPIOA_CLK_ENABLE();//开启时钟
        GPIO_InitTypeDef GPIO_InitStruct; 
        GPIO_InitStruct.IT=GPIO_IT_NONE;
        GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;//推挽输出
        GPIO_InitStruct.Pins=GPIO_PIN_12;
        GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
        GPIO_Init(CW_GPIOA, &GPIO_InitStruct);

        RGB_Color_Init();//初始化所有灯
}

 

随后根据时序的高低电平要求,先编写一个ns延时,由于当前使用主频为64mhz,可以算出一个机器指令所需时间大概为1/64=15ns,然后加上GPIO电平翻转时间即可。

 

/**************************
400ns延时
**************************/
void delay_400ns(void)//409
{
        __nop();__nop();__nop();__nop();__nop();//__nop();__nop();
}
/**************************
800ns延时
**************************/
void delay_800ns(void)//800
{
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
//        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
//        __nop();__nop();
}

 

然后根据时序所需的高低电平时间编写0,1指令

 

/**************************
发送1
**************************/
void RGB_Send1(void)
{
        RGB_H;
        delay_800ns();
        RGB_L;
        delay_400ns();
}
/**************************
发送0
**************************/
void RGB_Send0(void)
{
        RGB_H;
        delay_400ns();
        RGB_L;
        delay_800ns();
}

 

然后就可以向芯片发送指令了,一个颜色分为RGB三个色域,一个色域为8位,所以我们需要八位数据一起发送,编写如下代码:

 

/**************************
发送颜色数据,高位先行
**************************/
void RGB_send_Data(uint8_t Data)
{
        uint8_t i;
        for(i=0;i< 8;i++)
        {
                if(Data & 0x80)
                {
                        RGB_Send1();
                }
                else
                {
                        RGB_Send0();
                }
                Data< <=1;
        }
}

 

这样就可以向芯片发送指定的颜色数据啦,最后在封装一下,我们想要的要求是指定某个灯亮某种颜色,或者指定某个灯熄灭,不能影响到其他灯,所以我们定义一个数组来装下所有灯的颜色数据,到时候只需要改变数组中固定位置的值就可以直接改变颜色了,代码如下:

 

/**************************
显示颜色
n:第几个灯
R:红色
G:绿色
B:蓝色
**************************/
void Send_RGB(uint8_t n,uint8_t R,uint8_t G,uint8_t B)
{
        uint8_t i;
        RGB_Data[3*n-3]=G;
        RGB_Data[3*n-2]=R;
        RGB_Data[3*n-1]=B;
        for(i=0;i< 24;i++)
        {
                RGB_send_Data(RGB_Data[i]);
        }
        RGB_Reset();
}

 

最后在main函数编写如下代码(OLED显示代码不在此处列出)

 

int main(void)
{
        OLED_Init();//初始化
        OLED_ShowString(1,1,"Hello");//OLED显示字符串
        WS2812_Init();
        while(1)
        {
                Send_RGB(1,255,0,0);//255,0,0对应红色
                Delay_ms(500);
                Send_RGB(1,0,255,0);//255,0,0对应绿色
                Delay_ms(500);
                Send_RGB(1,0,0,255);//255,0,0对应蓝色
                Delay_ms(500);
        }
}

 

三、工作现象

在烧写代码之后,我们可以观察到以下现象,OLED第一行第一列显示HELLO,第一个RGB灯每隔500ms转换一次颜色,在红绿蓝三色之间反复切换。

智能小车


 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分