• 正文
    • 一模块来源
    • 二规格参数
    • 三移植过程
    • 四移植验证
  • 相关推荐
申请入驻 产业图谱

S2812彩灯:CW32F030C8T6开发板实现设置彩灯颜色的功能

02/11 08:47
900
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

WS2812E是一个集控制电路与发光电路于一体的智能外控LED光源。其外型与一个5050LED灯珠相同,每个 元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路,还包含有高精度的内部 振荡器可编程电流控制部分,有效保证了像素点光的颜色高度一致。

模块来源

模块实物展示:

资料链接:https://pan.baidu.com/s/1OkCpw8ooDyuw947V0b89Rw

资料提取码:AB12

规格参数

工作电压:3.7-5.3V

工作电流:16MA

控制方式:单总线

管脚数量:4 Pin(2.54mm间距排针

以上信息见厂家资料文件

移植过程

我们的目标是将例程移植至CW32F030C8T6开发板上【能够实现设置彩灯颜色的功能】。首先要获取资料,查看数据手册应如何实现读取数据,再移植至我们的工程。

3.1查看资料

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

3.2引脚选择

该模块有3个引脚,具体引脚连接见各引脚连接。

模块接线图

3.3移植至工程

移植步骤中的导入.c和.h文件与【CW32模块使用】DHT11温湿度传感器相同,只是将.c和.h文件更改为bsp_ws2812.c与bsp_ws2812.h。这里不再过多讲述,移植完成后面修改相关代码。

在文件bsp_ws2812.c中,编写如下代码。

/* * Change Logs: * Date           Author       Notes * 2024-06-24     LCKFB-LP    first version */#include "bsp_ws2812.h"#include "stdio.h"#include "math.h"

unsigned char LedsArray[WS2812_MAX * 3];      //定义颜色数据存储数组unsigned int  ledsCount   = WS2812_NUMBERS;   //定义实际彩灯默认个数unsigned int  nbLedsBytes = WS2812_NUMBERS*3; //定义实际彩灯颜色数据个数
void delay_0_30us(void){        __NOP;__NOP;__NOP;__NOP;__NOP;}

/****************************************************************** * 函 数 名 称:WS2812_GPIO_Init * 函 数 说 明:对WS2812引脚初始化 * 函 数 形 参:无 * 函 数 返 回:无 * 作       者:LC * 备       注:无******************************************************************/void WS2812_GPIO_Init(void){    GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化结构体
    RCC_DIN_ENABLE();        // 使能GPIO时钟
    GPIO_InitStruct.Pins = GPIO_DIN;                        // GPIO引脚    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;             // 推挽输出    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;                // 输出速度高    GPIO_Init(PORT_DIN, &GPIO_InitStruct);                  // 初始化
    GPIO_WritePin(PORT_DIN, GPIO_DIN, GPIO_Pin_RESET);}/****************************************************************** * 函 数 名 称:rgb_SetColor * 函 数 说 明:设置彩灯颜色 * 函 数 形 参:LedId控制的第几个灯  color颜色数据 * 函 数 返 回:无 * 作       者:LC * 备       注:在这里我将绿和红色进行颠倒,这样比较符合我们日常生活的红绿蓝的顺序******************************************************************/
void rgb_SetColor(unsigned char LedId, unsigned long color){    if( LedId > ledsCount )    {        return;    //to avoid overflow    }    LedsArray[LedId * 3]     = (color>>8)&0xff;    LedsArray[LedId * 3 + 1] = (color>>16)&0xff;    LedsArray[LedId * 3 + 2] = (color>>0)&0xff;}
/****************************************************************** * 函 数 名 称:rgb_SetRGB * 函 数 说 明:设置彩灯颜色(三原色设置) * 函 数 形 参:LedId控制的第几个灯 red红色数据  green绿色数据  blue蓝色数据 * 函 数 返 回:无 * 作       者:LC * 备       注:无******************************************************************/void rgb_SetRGB(unsigned char LedId, unsigned long red, unsigned long green, unsigned long blue){    unsigned long Color=red<<16|green<<8|blue;    rgb_SetColor(LedId,Color);}
/****************************************************************** * 函 数 名 称:rgb_SendArray * 函 数 说 明:发送彩灯数据 * 函 数 形 参:无 * 函 数 返 回:无 * 作       者:LC * 备       注:无******************************************************************/void rgb_SendArray(void){    unsigned int i;    //发送数据    for(i=0; i<nbLedsBytes; i++)        Ws2812b_WriteByte(LedsArray[i]);}
/****************************************************************** * 函 数 名 称:RGB_LED_Reset * 函 数 说 明:复位ws2812 * 函 数 形 参:无 * 函 数 返 回:无 * 作       者:LC * 备       注:低电平280us以上******************************************************************/void RGB_LED_Reset(void){        RGB_PIN_L();        delay_us(285);}
/****************************************************************** * 函 数 名 称:Ws2812b_WriteByte * 函 数 说 明:向WS2812写入单字节数据 * 函 数 形 参:byte写入的字节数据 * 函 数 返 回:无 * 作       者:LC * 备       注:1码的时序 = 高电平580ns~1us    再低电平220ns~420ns *              0码的时序 = 高电平220ns~380ns  再低电平580ns~1us******************************************************************/void Ws2812b_WriteByte(unsigned char byte){    int i = 0, k = 0;    for(i = 0; i < 8; i++ )    {        if( byte & (0x80 >> i) )//当前位为1        {            RGB_PIN_H();            delay_us(1);//0.75us            RGB_PIN_L();            __NOP;__NOP;__NOP;__NOP;__NOP;//0.25us        }        else//当前位为0        {            RGB_PIN_H();            __NOP;__NOP;__NOP;__NOP;__NOP;//0.25us            RGB_PIN_L();            delay_us(1);//0.833us        }    }}

在文件bsp_ws2812.h中,编写如下代码。

/* * Change Logs: * Date           Author       Notes * 2024-06-24     LCKFB-LP    first version */
#ifndef _BSP_WS2812_H_#define _BSP_WS2812_H_
#include "board.h"
#define RCC_DIN_ENABLE()    __RCC_GPIOB_CLK_ENABLE()#define PORT_DIN            CW_GPIOB#define GPIO_DIN            GPIO_PIN_12

//用户修改参数区//#define WS2812_FREQUENCY#define RGB_PIN_L()       GPIO_WritePin(PORT_DIN, GPIO_DIN, GPIO_Pin_RESET)  //控制彩灯引脚(需要配置为强推挽输出)#define RGB_PIN_H()       GPIO_WritePin(PORT_DIN, GPIO_DIN, GPIO_Pin_SET)    //控制彩灯引脚(需要配置为强推挽输出)#define WS2812_MAX        8                        //彩灯最大个数#define WS2812_NUMBERS    8                        //彩灯个数

#define RED               0xff0000                  //红色#define GREEN             0x00ff00                  //绿色#define BLUE              0x0000ff                  //蓝色#define BLACK             0x000000                  //熄灭#define WHITE             0xffffff                  //白色


//8.3 -8  0.000000083//4.16 -9 0.00000000416void Ws2812b_WriteByte(unsigned char byte);//发送一个字节数据(@12.000MHz,理论每个机器周期83ns,测试约为76ns)void setLedCount(unsigned char count);//设置彩灯数目,范围0-25.unsigned char getLedCount();//彩灯数目查询函数void rgb_SetColor(unsigned char LedId, unsigned long color);//设置彩灯颜色void rgb_SetRGB(unsigned char LedId, unsigned long red, unsigned long green, unsigned long blue);//设置彩灯颜色void rgb_SendArray();//发送彩灯数据
void WS2812_GPIO_Init(void);
void RGB_LED_Write1(void);void RGB_LED_Reset(void);

#endif

移植验证

在自己工程中的main主函数中,编写如下。

/* * Change Logs: * Date           Author       Notes * 2024-06-24     LCKFB-LP    first version */#include "board.h"#include "stdio.h"#include "bsp_uart.h"#include "bsp_ws2812.h"
uint8_t Co = 100;unsigned int buff[]={RED,GREEN,BLUE,WHITE};
int32_t main(void){    int i = 0;
    board_init();
    uart1_init(115200);
    WS2812_GPIO_Init();    printf("Start--->rn");
    while(1)    {        for( i = 0; i < 8; i++ )        {            rgb_SetColor(i,buff[i%3]);            rgb_SendArray();            delay_ms(10);        }        delay_ms(3000);
        i = 0;        while( Co )        {            rgb_SetColor((i+0)%8,buff[0]);            rgb_SetColor((i+1)%8,buff[1]);            rgb_SetColor((i+2)%8,buff[2]);            rgb_SetColor((i+3)%8,buff[3]);
            rgb_SetColor((i+4)%8,BLACK);            rgb_SetColor((i+5)%8,BLACK);            rgb_SetColor((i+6)%8,BLACK);            rgb_SetColor((i+7)%8,BLACK);
            rgb_SendArray();            delay_ms(200);            Co--;            i++;        }        Co = 100;    }}

移植现象:三秒前八个灯全亮,后面循环流水灯显示。

模块移植成功案例代码:

链接:https://pan.baidu.com/s/1boqb5UkpomK2avKNqAjz-w?pwd=LCKF

提取码:LCKF

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

以开放、共享、互助为理念,致力于构建武汉芯源半导体CW32系列MCU生态社区。无论是嵌入式MCU小自还是想要攻破技术难题的工程师,亦或是需求解决方案的产品经理都可在CW32生态社区汲取营养、共同成长。

B站