//在WS2812.h文件里面定义
#ifndef __WS2812_H
#define __WS2812_H
#include "main.h"
#include "stdint.h"
#define WS2812_TIM &htim1
#define WS2812_TIM_Channel TIM_CHANNEL_1
#define WS2812_Code_1 (62u)
#define WS2812_Code_0 (27u)
#define WS2812_Num 61
void WS2812_uint32ToData(uint32_t Data, uint32_t *Ret);
void WS2812_Start(void);
void WS2812_Send(void);
void ws2812_breath(void);
void ws2812_dan(void);
void ws2812_paoma(void);
void ws2812_an(void);
void light_mode_music_set(uint8_t count);
void light_music_process();
#endif /* __WS2812_H */
//在WS2812.c文件里面定义
#include "WS2812.h"
extern TIM_HandleTypeDef htim1;
extern DMA_HandleTypeDef hdma_timi_ch1;
uint32_t WS2812_SendBuf0[25] = {0}; //发送缓冲区0
uint32_t WS2812_SendBuf1[25] = {0}; //发送缓冲区1
const uint32_t WS2812_Rst[240] = {0};
uint32_t WS2812_En = 0;
uint32_t WS2812_Data[WS2812_Num] = {0};
uint8_t g_ws2812_count=0;
//跑马灯函数
void ws2812_paoma(void)
{
static uint8_t state = 0; // 跑马灯状态,初始为0
static uint32_t colors[3][3] = {
{0xFF0000, 0x00FF00, 0x0000FF}, // 红、绿、蓝
{0x00FF00, 0x0000FF, 0xFF0000}, // 绿、蓝、红
{0x0000FF, 0xFF0000, 0x00FF00} // 蓝、红、绿
}; //二维数组
// 根据状态设置灯珠颜色
for (uint8_t i = 0; i < WS2812_Num; i++) {
WS2812_Data[i] = colors[state][i % 3];
}
// 启动WS2812发送函数
WS2812_Start();
// 更新状态
state = (state + 1) % 3;
// 延迟一段时间
HAL_Delay(500); // 控制每个颜色显示的时间
}
//单色灯依次点亮函数
void ws2812_dan(void)
{
static uint8_t LED_index = 0; // 初始化LED索引
static uint32_t color = 0xFF0000; // 初始化颜色为红色
// 将所有LED设置为黑色
for(uint8_t i = 0; i < WS2812_Num; i++)
{
WS2812_Data[i] = 0x000000;
}
// 设置当前灯珠颜色
WS2812_Data[LED_index] = color;
// 更新LED索引
LED_index++;
if(LED_index >= WS2812_Num)
{
LED_index = 0; // 如果达到最后一个灯珠,重新开始
}
// 启动WS2812发送函数
WS2812_Start();
// 延迟一段时间
HAL_Delay(100); // 控制每个颜色显示的时间
}
// 呼吸灯函数
void ws2812_breath(void)
{
static uint8_t RGB_flag=0;
static uint32_t color=0x000000;
if(RGB_flag==0)
{
if(color==0xff0000)
{
RGB_flag=1;
}
else
{
color+=0x110000;
}
}
if(RGB_flag==1)
{
if(color==0x000000)
{
RGB_flag=0;
}
else
{
color-=0x110000;
}
}
for(uint8_t i = 0;i<WS2812_Num;i++)
{
WS2812_Data[i]=color;
}
WS2812_Start();
HAL_Delay(200);
}
void WS2812_uint32ToData(uint32_t Data, uint32_t *Ret)
{
uint8_t R=0,G=0,B=0;
uint32_t zj = Data;
uint8_t *p = (uint8_t *)&zj;
B = *(p);
G = *(p+1);
R = *(p+2);
zj = (G<<16)|(R<<8)|B;
for(uint8_t i = 0;i < 24;i++)
{
if(zj&0x800000)
Ret[i] = WS2812_Code_1;
else
Ret[i] = WS2812_Code_0;
zj<<=1;
}
Ret[24] = 0;
}
void WS2812_Start(void)
{
HAL_TIM_PWM_Start_DMA(WS2812_TIM, WS2812_TIM_Channel, (uint32_t *)WS2812_Rst, 240);
WS2812_uint32ToData(WS2812_Data[0],WS2812_SendBuf0);
WS2812_En = 1;
}
void WS2812_Send(void)
{
static uint8_t j = 0;
static uint8_t ins = 0;
if(WS2812_En == 1)
{
if(j == WS2812_Num)
{
j=0;
HAL_TIM_PWM_Stop_DMA(WS2812_TIM, WS2812_TIM_Channel);
WS2812_En = 0;
}
j++;
if(ins == 0)
{
HAL_TIM_PWM_Stop_DMA(WS2812_TIM, WS2812_TIM_Channel);
HAL_TIM_PWM_Start_DMA(WS2812_TIM, WS2812_TIM_Channel, WS2812_SendBuf0, 25);
WS2812_uint32ToData(WS2812_Data[j],WS2812_SendBuf1);
ins = 1;
}
else
{
HAL_TIM_PWM_Stop_DMA(WS2812_TIM, WS2812_TIM_Channel);
HAL_TIM_PWM_Start_DMA(WS2812_TIM, WS2812_TIM_Channel, WS2812_SendBuf1, 25);
WS2812_uint32ToData(WS2812_Data[j],WS2812_SendBuf0);
ins = 0;
}
}
}
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
WS2812_Send();
}
基于STM32F103C8T6最小系统的WS2812灯带函数
最新推荐文章于 2025-05-05 10:02:09 发布