基于STM32的HAL库的WS2812幻彩灯驱动程序

52 篇文章 0 订阅
49 篇文章 1 订阅

1、WS2812幻彩灯带有三条接线,5V、GND和控制信号线,利用单片机的SPI引脚可以发出不同频率协议的脉冲即可实现对幻彩灯带的各个灯珠的颜色和亮灭的控制。

2、幻彩灯带驱动代码如下:

(1)ws2812.c

#include "ws2812.h"
#include "spi.h"
#include "dma.h"

// 常用的颜色
const RGBColor_TypeDef RED      = {30 ,0  ,  0};
const RGBColor_TypeDef GREEN    = {0  , 30,  0};
const RGBColor_TypeDef BLUE     = {0  ,  0, 30};
const RGBColor_TypeDef YELLOW   = { 30, 30,  0};
const RGBColor_TypeDef MAGENTA  = { 30,  0, 30};
const RGBColor_TypeDef BLACK    = {  0,  0,  0};
const RGBColor_TypeDef WHITE    = { 30, 30, 30};

//模拟bit码:0xC0 为 0,0xF8 为 1
const uint8_t code[]={0xC0,0xF8};
//灯颜色缓存区
RGBColor_TypeDef RGB_DAT[RGB_NUM];

//SPI底层发送接口,一次发24个字节,相当于1个灯
extern DMA_HandleTypeDef hdma_spi3_tx;
static void SPI_Send(uint8_t *SPI_RGB_BUFFER)
{
  /* 判断上次DMA有没有传输完成 */
	while(HAL_DMA_GetState(&hdma_spi3_tx) != HAL_DMA_STATE_READY);
  /* 发送一个(24bit)的 RGB 数据到 2812 */
	HAL_SPI_Transmit_DMA(&hspi3,SPI_RGB_BUFFER,24);  
}
//颜色设置函数,传入 ID 和 颜色,进而设置缓存区
void RGB_Set_Color(uint8_t LedId, RGBColor_TypeDef Color)  
{
  if(LedId < RGB_NUM)
	{
		RGB_DAT[LedId].G = Color.G;
		RGB_DAT[LedId].R = Color.R;
		RGB_DAT[LedId].B = Color.B;
	}
}
//刷新函数,将颜色缓存区刷新到WS2812,输入参数是指定的刷新长度
void RGB_Reflash(uint8_t reflash_num)
{
	static uint8_t RGB_BUFFER[24]={0};
	uint8_t dat_b,dat_r,dat_g;
	//将数组颜色转化为 24 个要发送的字节数据
	if(reflash_num>0 && reflash_num<=RGB_NUM)
	{
		for(int i=0;i<reflash_num;i++)
		{
			dat_g = RGB_DAT[i].G;
			dat_r = RGB_DAT[i].R;
			dat_b = RGB_DAT[i].B;
			for(int j=0;j<8;j++)
			{
				RGB_BUFFER[7-j] =code[dat_g & 0x01];
				RGB_BUFFER[15-j]=code[dat_r & 0x01];
				RGB_BUFFER[23-j]=code[dat_b & 0x01];
				dat_g >>=1;
				dat_r >>=1;
				dat_b >>=1;
			}
			SPI_Send(RGB_BUFFER);
		}
	}
}
//复位函数
void RGB_RST(void)
{
	uint8_t dat[100] = {0};
  /* 判断上次DMA有没有传输完成 */
	while(HAL_DMA_GetState(&hdma_spi3_tx) != HAL_DMA_STATE_READY);
  /* RGB RESET */
	HAL_SPI_Transmit_DMA(&hspi3,dat,100); 
	HAL_Delay(10);
}

//常用颜色的点亮测试函数
void RGB_RED(uint16_t RGB_LEN)
{
  uint8_t i;
  for(i=0;i<RGB_LEN;i++)  
    RGB_Set_Color(i,RED);
	RGB_Reflash(RGB_LEN);
}
void RGB_GREEN(uint16_t RGB_LEN)
{
  uint8_t i;
  for(i=0;i<RGB_LEN;i++)  
    RGB_Set_Color(i,GREEN);
	RGB_Reflash(RGB_LEN);
}
void RGB_BLUE(uint16_t RGB_LEN)
{
  uint8_t i;
  for(i=0;i<RGB_LEN;i++)  
    RGB_Set_Color(i,BLUE);
	RGB_Reflash(RGB_LEN);
}
void RGB_YELLOW(uint16_t RGB_LEN)
{
  uint8_t i;
  for(i=0;i<RGB_LEN;i++)  
    RGB_Set_Color(i,YELLOW);
	RGB_Reflash(RGB_LEN);
}
void RGB_MAGENTA(uint16_t RGB_LEN)
{
  uint8_t i;
  for(i=0;i<RGB_LEN;i++)  
    RGB_Set_Color(i,MAGENTA);
	RGB_Reflash(RGB_LEN);
}
void RGB_BLACK(uint16_t RGB_LEN)
{
  uint8_t i;
  for(i=0;i<RGB_LEN;i++)  
    RGB_Set_Color(i,BLACK);
	RGB_Reflash(RGB_LEN);
}
void RGB_WHITE(uint16_t RGB_LEN)
{
  uint8_t i;
  for(i=0;i<RGB_LEN;i++)  
    RGB_Set_Color(i,WHITE);
	RGB_Reflash(RGB_LEN);
}

(2)ws2812.h

#ifndef __WS2812_H
#define __WS2812_H

#include "main.h"

typedef struct				//颜色结构体
{
  uint8_t R;
  uint8_t G;
  uint8_t B;
}RGBColor_TypeDef;

#define RGB_NUM    60	// RGB数量

// 复位函数
void RGB_RST(void);
// 颜色设置函数
void RGB_Set_Color(uint8_t LedId, RGBColor_TypeDef Color);
// RGB 刷新函数
void RGB_Reflash(uint8_t reflash_num);
	
// 各种颜色测试
void RGB_RED(uint16_t RGB_LEN);		//红
void RGB_GREEN(uint16_t RGB_LEN);		//绿
void RGB_BLUE(uint16_t RGB_LEN);		//蓝
void RGB_YELLOW(uint16_t RGB_LEN);		//黄
void RGB_MAGENTA(uint16_t RGB_LEN);	//紫
void RGB_BLACK(uint16_t RGB_LEN);		//黑
void RGB_WHITE(uint16_t RGB_LEN);		//白

#endif /* __WS2812_H */

 (3)main函数中的调用

 while (1)
  {
		
		
		RGB_WHITE(60);
	HAL_Delay(100);
	RGB_YELLOW(59);
	HAL_Delay(100);
	RGB_BLUE(58);
	HAL_Delay(100);	
	RGB_GREEN(57);
	HAL_Delay(100);
  RGB_RED(56);
	HAL_Delay(100);	
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

需要注意的是,还需要cubeMX开启DMA和SPI,并在while循环之前调用

  MX_SPI3_Init();  MX_DMA_Init();(但这两句为自动生成,只要开启DMA和SPI就行)

ws2812b是一种智能彩灯,在STM32上使用HAL库进行编程时,可以利用PWM和DMA控制来控制彩灯的颜色和亮度。 PWM(脉宽调制)是一种常用的控制电子设备亮度的方法,通过改变PWM信号的占空比即高电平时间和低电平时间的比例,可以控制灯光的亮度。对于ws2812b彩灯,它需要接收到一串特定的脉冲信号来控制灯光的颜色和亮度,因此我们可以利用PWM信号来模拟这个特定的脉冲信号。 在使用HAL库进行编程时,可以利用定时器和PWM功能来生成脉冲信号。首先,我们需要初始化定时器和PWM通道,然后设置定时器的计数周期和预分频值,以确定脉冲信号的频率。接下来,我们可以通过改变PWM通道的CCR寄存器的值来改变脉冲信号的占空比,从而控制灯光的亮度。通过反复改变CCR寄存器的值,即可实现灯光的渐变效果。 为了实现更高效的控制,可以结合使用DMA(直接存储器访问)功能。DMA可以在处理器和外设之间直接传输数据,减轻CPU的负担。对于控制彩灯来说,我们可以把存储颜色和亮度信息的数组存放在内存中,然后通过DMA传输到PWM寄存器中,从而控制彩灯。通过配置DMA通道和中断,可以实现定时更新彩灯的效果。 总之,通过利用STM32HAL库,结合PWM和DMA控制,我们可以方便地对ws2812b彩灯进行编程,实现灯光的颜色和亮度控制,使其呈现出丰富多彩的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jacklood

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值