0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

CW32生态社区 来源:CW32生态社区 作者:CW32生态社区 2026-01-05 16:35 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一、WS2812介绍

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

主要特点

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

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

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

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

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

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

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

wKgZO2lVB06ANXwXAAAiTuM_e4g136.jpg

原理图

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

wKgZPGlVB06AOXP9AACKtvcP-Jw248.jpg

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

通信原理

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

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

控制方式

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

wKgZO2lVB0-AA1K_AABLB1JMq9U344.jpg

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

控制时序

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

wKgZPGlVB0-AanWlAAEAeGtKRK0435.jpg

发送一位数据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转换一次颜色,在红绿蓝三色之间反复切换。

wKgZO2lVB0-AIHi2AAAeGEdmbbk323.jpg


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

    关注

    244

    文章

    24792

    浏览量

    693700
  • RGB
    RGB
    +关注

    关注

    4

    文章

    841

    浏览量

    62346
  • 驱动电路
    +关注

    关注

    160

    文章

    1634

    浏览量

    112041
  • 智能小车
    +关注

    关注

    87

    文章

    566

    浏览量

    83563
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    CW32L012/F030X1智能小车——超声波模块配置

    SR04超声波模块是一款广泛应用的测距传感器,主要用于使用超声波测量物体与传感器之间的距离。它是一个成本低廉、精度较高且易于使用的传感器,常用于机器人、智能家居、无人机、汽车防撞系统等项目。
    的头像 发表于 01-05 16:54 3182次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>——超声波模块配置

    CW32L012/F030X1智能小车——使用蓝牙模块通讯

    主控板配套的是一款低功耗蓝牙模块,适用于短距离无线通信。该模块通常被用于各种嵌入式项目,如物联网(IoT)设备、手机配件、智能家居设备、医疗设备等。
    的头像 发表于 04-01 16:54 3424次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>——使用蓝牙模块通讯

    STM32F030 MDA+PWM驱动ws2812b,起始的50US的低电平是怎么产生?

    STM32F030 MDA+PWM 驱动 ws2812b,起始的50US的低电平怎么产生? 现在dma+pwm,倒是可以产生一个800K hz的驱动数据,但是
    发表于 04-12 07:23

    【RA4L1-SENSOR】点亮 WS2812 全彩点阵屏

    通过单总线方式控制,只需一个 IO 口,就可以点亮数千个灯珠。 这里使用 RA4L1 点亮 WS2812 灯珠,效果如下: WS2812 可以使用 IO 模拟时序控制,也可以使用 PWM
    发表于 06-09 12:48

    **CW32L012****开发评估板的第一个程序**

    CW32L012****开发评估板的第一个程序 最近以15.99在CW32生态社区入手了这块CW32L012开发评估板,我迫不及待的烧录进电灯程序,看看这块板子是否是正常的,能否满足我后面的学习
    发表于 11-22 00:09

    CW32L012小型机器人控制评估板活动 四足机器人+智能小车 开箱评测

    CW32L012活动相关资料链接:https://dwi41yhz703.feishu.cn/wiki/B1Ihw31ebiX0vkkhQr2cINnkn1g 小型机器人+智能小车
    发表于 11-24 23:44

    STM32F103C8T6+PWM+DMA驱动WS2812灯带的方法

    #STM32+PWM+DMA驱动 WS2812灯带#文章目录1.理论:2代码:理论:使用STM32F103C8T6驱动
    发表于 02-22 06:59

    WS2812驱动的总结和时序的详细资料分析

    都是用PWM驱动,想要控制亮度、颜色就要分别控制每个引脚上的PWM占空比,想要驱动多个LED就更麻烦了。恨的是WS2812对时序的要求比较高,对低速单片机不太友好。今天我们就详细谈一谈WS28
    发表于 08-01 17:35 65次下载
    <b class='flag-5'>WS2812</b><b class='flag-5'>驱动</b>的总结和时序的详细资料分析

    STM32使用LL库PWM的DMA模式驱动ws2812

    驱动n个,当然n是有限制的。时序超级简单,也有一定难度。类似的帖子网上有很多,在此不再赘述。WS2812驱动方式大概有以下几种:1.使用GPIO模拟,中间加延时实现“0”、“
    发表于 11-30 10:21 67次下载
    STM32使用LL库PWM的DMA模式<b class='flag-5'>驱动</b><b class='flag-5'>ws2812</b>

    STM32F103C8T6+PWM+DMA驱动 WS2812灯带

    #STM32+PWM+DMA驱动 WS2812灯带#文章目录1.理论:2代码:理论:使用STM32F103C8T6驱动
    发表于 12-27 19:29 229次下载
    STM32<b class='flag-5'>F</b>103C8T6+PWM+DMA<b class='flag-5'>驱动</b> <b class='flag-5'>WS2812</b>灯带

    PWM+DMA 驱动 WS2812

    PWM+DMA 驱动 WS2812一、项目要求(主要目的)使用 PWM+DMA 的方式驱动 WS2812B, 并每隔 800ms 随机显示不同颜色。(附加目的)探索一下 STM32 的
    发表于 12-28 19:14 118次下载
    PWM+DMA <b class='flag-5'>驱动</b> <b class='flag-5'>WS2812</b>

    使用ESP8266驱动WS2812彩灯

    本篇介绍ESP8266使用NeoPixel库来驱动IOT Kit板载WS2812彩灯。
    的头像 发表于 05-19 14:31 5750次阅读
    使用ESP8266<b class='flag-5'>驱动</b><b class='flag-5'>WS2812</b>彩灯

    CW32L012与STM32F103的三角运算性能对比

    没有硬件浮点运算单元。 但在运算三角函数时,CW32L012支持CORDIC算法。 二、 三角运算性能具体分析 1:标准库浮点运算(如 math.h 的 sinf, cosf) 这是最常用但也是最慢的方式。 STM32F103C
    的头像 发表于 12-29 15:32 2636次阅读
    <b class='flag-5'>CW32L012</b>与STM32<b class='flag-5'>F</b>103的三角运算性能对比

    CW32L012/F030X1智能小车--电机正反转控制

    RZ7899是一种高性能电机驱动芯片,广泛应用于各种电机控制场合,特别是在步进电机和直流电机的驱动中。
    的头像 发表于 04-02 16:48 1210次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>--电机正反转控制

    CW32L012/F030X1智能小车--电机调速控制

    PWM(Pulse Width Modulation脉宽调制)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号任然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有,要么完全无。比如我们的电压输出是5v的,那么经过改变PWM的占空比,可以达到在一定时间内输出3.3V或者1.3V的效果
    的头像 发表于 04-02 16:49 1357次阅读
    <b class='flag-5'>CW32L012</b>/<b class='flag-5'>F030</b><b class='flag-5'>灵</b><b class='flag-5'>眸</b><b class='flag-5'>X1</b><b class='flag-5'>智能</b><b class='flag-5'>小车</b>--电机调速控制