使用STM32单片机驱动WS2812B【外设篇】

简介


引脚

 注:带三角形的一头是VSS


特性


 时序

 上图输入码型的意思是,输入是0还是1,是通过对高低电平的不同延时,来区分0和1的输入

注:具体高低电平的延长时间,参考手册。 

1)高位先发

2)在级联时,每经过一个像素点传输,信号减少24bit

3)24位代表RGB,每8位代表一个颜色,不过WS2812B中是GRB的顺序


 代码

rgb.c文件

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "rgb.h"

//RGB存储,总共四个灯珠
uint8_t rgb_Ram[12]= {0};

/*****************************************************************************
* 功  能:ns延时
* 参  数:xns 多少ns
* 返回值:无
*****************************************************************************/
void Delay_ns(uint32_t xns) {
    while(xns--)
        __NOP();
}

/*****************************************************************************
* 功  能:发送Reset
* 参  数:无
* 返回值:无
*****************************************************************************/
void Ws2812b_Reset(void)
{
    Delay_us(55);
}

/*****************************************************************************
* 功  能:发送0
* 参  数:无
* 返回值:无
*****************************************************************************/
void Ws2812b_Send0Code(void)
{
    RGB_HIGH;
    Delay_ns(2);

    RGB_LOW;
    Delay_ns(10);
}

/*****************************************************************************
* 功  能:发送1
* 参  数:无
* 返回值:无
*****************************************************************************/
void Ws2812b_Send1Code(void)
{
    RGB_HIGH;
    Delay_ns(10);

    RGB_LOW;
    Delay_ns(2);
}

/*****************************************************************************
* 功  能:设置对应RGB的颜色
* 参  数:several 第几个RGB
*		  r 	   RGB中的R
*		  g 	   RGB中的G
*		  b 	   RGB中的B
* 返回值:无
*****************************************************************************/
void Ws2812b_SetRGB(uint8_t several,uint8_t r,uint8_t g,uint8_t b)
{
    rgb_Ram[(several-1)*3+0]=g;
    rgb_Ram[(several-1)*3+1]=r;
    rgb_Ram[(several-1)*3+2]=b;
}

/*****************************************************************************
* 功  能:Refresh,点亮几个灯
* 参  数:several 点亮几个RGB
* 返回值:无
*****************************************************************************/
void Ws2812b_Refresh(uint8_t several)
{
    uint8_t i =0,j =0;
    for(i=0; i<several*3; i++)
    {
        for(j=0; j<8; j++)
        {
            if(rgb_Ram[i]&(0x80>>j)) {
                Ws2812b_Send1Code();
            }
            else {
                Ws2812b_Send0Code();
            }
        }
    }
}

/*****************************************************************************
* 功  能:初始化RGB
* 参  数:无
* 返回值:无
*****************************************************************************/
void RGB_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin=RGB;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);

    RGB_LOW;

    SetRGB(1,Green);
    SetRGB(2,Yellow);
    SetRGB(3,Red);
    SetRGB(4,Blue);
}

/*****************************************************************************
* 功  能:点亮RGB
* 参  数:无
* 返回值:无
*****************************************************************************/
void LightenRGB(void)
{
    Ws2812b_Reset();
    Ws2812b_Refresh(4);
}





 rgb.h文件

#ifndef __RGB_H
#define __RGB_H

//引脚定义
#define RGB GPIO_Pin_9

#define RGB_HIGH GPIOB->BSRR = GPIO_Pin_9
#define RGB_LOW GPIOB->BRR = GPIO_Pin_9

//颜色定义
#define Green 0 ,255, 0	
#define Pink 255 ,192 ,203	
#define Red 255 ,0 ,0	
#define Blue 0,0 ,255	
#define Yellow 255 ,255, 0

void RGB_Init(void);
void LightenRGB(void);
void Ws2812b_SetRGB(uint8_t several,uint8_t r,uint8_t g,uint8_t b);
#endif

1)复制粘贴直接调用LightenRGB函数,就可以运行(需要添加Delay头文件)

2)时间需要自己调试

3)由于是ns级别的,推荐使用

翻转IO口

4)stm32的时钟周期在72mhz的系统时钟下为13.89ns

5)一个__nop();语句占用的是13.89ns


END~~

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要点亮WS2812B LED,需要使用STM32的定时器和DMA功能。以下是一些基本步骤: 1. 配置STM32的定时器和DMA: 首先,需要根据WS2812B的数据协议,设置一个定时器来控制数据传输的时间。一般来说,WS2812B的每个数据位都是由一个高电平和一个低电平组成的,高电平的时间决定了数据位为0还是1。在STM32中,可以使用TIM定时器的PWM模式来生成这些高电平和低电平。然后,使用DMA来将数据从内存中传输到定时器的输出缓冲区中。 2. 编写代码来生成WS2812B数据: 在STM32中,可以使用数组来存储要发送的WS2812B数据。每个数据位都需要编码成一个24位的数据,其中每8位代表一个颜色通道(红、绿、蓝)。可以使用位运算符来生成这些数据。例如,以下代码片段演示了如何生成一个红色的LED数据: ```c uint8_t red = 255; uint8_t green = 0; uint8_t blue = 0; uint32_t data = ((uint32_t)green << 16) | ((uint32_t)red << 8) | (uint32_t)blue; // 将数据存储到数组中 ws2812b_data[index] = data; ``` 其中,`index`是要点亮的LED的索引,`ws2812b_data`是存储数据的数组。 3. 启动DMA传输: 一旦数据准备好了,就可以启动DMA传输了。使用`HAL_TIM_PWM_Start_DMA()`函数来启动定时器和DMA传输。在传输完成之前,最好禁用中断以避免干扰。 4. 等待DMA传输完成: 一旦DMA传输完成,可以使用`HAL_TIM_PWM_Stop_DMA()`函数停止定时器和DMA传输。然后,等待一段时间让WS2812B处理数据,并且不要忘记重新启用中断。 以上是大致的步骤,当然在实际的应用中还需要考虑一些细节问题。在编写代码之前,最好查阅WS2812B的数据手册,并且参考一些已有的代码或库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值