来一套基于STM32单片机控制WS2812实现10种灯光效果的代码
时间: 2024-01-21 18:19:15 浏览: 182
好的,以下是基于STM32单片机控制WS2812实现10种灯光效果的代码,仅供参考:
```
#include "stm32f10x.h"
/*********** WS2812灯带控制IO口配置 ***********/
#define WS2812_GPIO_PORT GPIOB
#define WS2812_GPIO_PIN GPIO_Pin_0
/*********** WS2812灯带控制参数配置 ***********/
#define LED_NUM 10 // 灯珠数量
#define COLOR_NUM 3 // 颜色数量
#define LED_TOTAL (LED_NUM * COLOR_NUM) // 灯总数
#define RESET_TIME 300 // 重置时间(单位:us)
/*********** 颜色定义 ***********/
#define RED 0xFF0000 // 红色
#define GREEN 0x00FF00 // 绿色
#define BLUE 0x0000FF // 蓝色
#define YELLOW 0xFFFF00 // 黄色
#define MAGENTA 0xFF00FF // 品红
#define CYAN 0x00FFFF // 青色
#define WHITE 0xFFFFFF // 白色
#define BLACK 0x000000 // 黑色
/*********** 函数声明 ***********/
void delay_us(uint32_t us);
void WS2812_SendData(uint32_t data);
void WS2812_SendColor(uint32_t color);
void WS2812_SendDataArray(uint32_t *array, uint16_t len);
void WS2812_SetAllColor(uint32_t color);
void WS2812_Rainbow();
void WS2812_FadeInOut(uint32_t c, uint8_t wait);
void WS2812_TheaterChaseRainbow(uint8_t wait);
void WS2812_RainbowCycle(uint8_t wait);
void WS2812_TheaterChase(uint32_t c, uint8_t wait);
/*********** 主函数 ***********/
int main(void)
{
uint32_t color;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIOB时钟
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = WS2812_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(WS2812_GPIO_PORT, &GPIO_InitStructure); // 配置GPIO口
while (1)
{
WS2812_SetAllColor(RED); // 灯带全亮红色
delay_us(RESET_TIME); // 重置时间
WS2812_SetAllColor(GREEN); // 灯带全亮绿色
delay_us(RESET_TIME); // 重置时间
WS2812_SetAllColor(BLUE); // 灯带全亮蓝色
delay_us(RESET_TIME); // 重置时间
color = YELLOW;
WS2812_FadeInOut(color, 50); // 呼吸黄色
WS2812_FadeInOut(color, 50);
WS2812_FadeInOut(color, 50);
WS2812_Rainbow(); // 彩虹效果
color = CYAN;
WS2812_TheaterChase(color, 50); // 彩虹跑道
color = MAGENTA;
WS2812_TheaterChase(color, 50);
color = YELLOW;
WS2812_TheaterChase(color, 50);
WS2812_RainbowCycle(20); // 彩虹循环
WS2812_TheaterChaseRainbow(50); // 彩虹跑道
}
}
/*********** 延时函数 ***********/
void delay_us(uint32_t us)
{
while(us--)
{
__NOP();
__NOP();
}
}
/*********** 发送数据函数 ***********/
void WS2812_SendData(uint32_t data)
{
uint8_t i;
for(i = 0; i < 24; i++)
{
if(data & 0x800000)
{
WS2812_GPIO_PORT->BSRR = WS2812_GPIO_PIN;
delay_us(0.7);
WS2812_GPIO_PORT->BRR = WS2812_GPIO_PIN;
delay_us(0.6);
}
else
{
WS2812_GPIO_PORT->BSRR = WS2812_GPIO_PIN;
delay_us(0.35);
WS2812_GPIO_PORT->BRR = WS2812_GPIO_PIN;
delay_us(0.8);
}
data <<= 1;
}
}
/*********** 发送颜色函数 ***********/
void WS2812_SendColor(uint32_t color)
{
uint8_t i;
for(i = 0; i < 8; i++)
{
if(color & 0x80)
{
WS2812_GPIO_PORT->BSRR = WS2812_GPIO_PIN;
delay_us(0.7);
WS2812_GPIO_PORT->BRR = WS2812_GPIO_PIN;
delay_us(0.6);
}
else
{
WS2812_GPIO_PORT->BSRR = WS2812_GPIO_PIN;
delay_us(0.35);
WS2812_GPIO_PORT->BRR = WS2812_GPIO_PIN;
delay_us(0.8);
}
color <<= 1;
}
}
/*********** 发送数据数组函数 ***********/
void WS2812_SendDataArray(uint32_t *array, uint16_t len)
{
uint16_t i;
for(i = 0; i < len; i++)
{
WS2812_SendColor(array[i]);
}
}
/*********** 设置所有灯珠颜色函数 ***********/
void WS2812_SetAllColor(uint32_t color)
{
uint32_t array[LED_TOTAL];
uint16_t i;
for(i = 0; i < LED_NUM; i++)
{
array[i * COLOR_NUM] = color;
array[i * COLOR_NUM + 1] = color;
array[i * COLOR_NUM + 2] = color;
}
WS2812_SendDataArray(array, LED_TOTAL);
}
/*********** 彩虹效果函数 ***********/
void WS2812_Rainbow()
{
uint32_t array[LED_TOTAL];
uint16_t i, j;
uint8_t r, g, b;
for(j = 0; j < 256; j++) // hue
{
for(i = 0; i < LED_NUM; i++)
{
HsvToRgb(j, 255, 255, &r, &g, &b);
array[i * COLOR_NUM] = (uint32_t)g << 16 | (uint32_t)r << 8 | b;
HsvToRgb(j + 128, 255, 255, &r, &g, &b);
array[i * COLOR_NUM + 1] = (uint32_t)g << 16 | (uint32_t)r << 8 | b;
HsvToRgb(j + 64, 255, 255, &r, &g, &b);
array[i * COLOR_NUM + 2] = (uint32_t)g << 16 | (uint32_t)r << 8 | b;
}
WS2812_SendDataArray(array, LED_TOTAL);
delay_us(20000);
}
}
/*********** 呼吸效果函数 ***********/
void WS2812_FadeInOut(uint32_t c, uint8_t wait)
{
uint8_t r, g, b;
uint16_t i, j;
for(j = 0; j < 256; j++)
{
r = (c & 0xFF0000) >> 16;
g = (c & 0x00FF00) >> 8;
b = (c & 0x0000FF);
for(i = 0; i < LED_NUM; i++)
{
WS2812_SendColor(((uint32_t)r * j / 255) << 16 | ((uint32_t)g * j / 255) << 8 | ((uint32_t)b * j / 255));
}
delay_us(wait * 1000 / 256);
}
for(j = 255; j > 0; j--)
{
r = (c & 0xFF0000) >> 16;
g = (c & 0x00FF00) >> 8;
b = (c & 0x0000FF);
for(i = 0; i < LED_NUM; i++)
{
WS2812_SendColor(((uint32_t)r * j / 255) << 16 | ((uint32_t)g * j / 255) << 8 | ((uint32_t)b * j / 255));
}
delay_us(wait * 1000 / 256);
}
}
/*********** 彩虹跑道函数 ***********/
void WS2812_TheaterChaseRainbow(uint8_t wait)
{
uint32_t array[LED_TOTAL];
uint16_t i, j;
uint8_t r, g, b;
for(j = 0; j < 256; j++) // hue
{
for(i = 0; i < LED_NUM; i += 3)
{
HsvToRgb(j, 255, 255, &r, &g, &b);
array[i] = (uint32_t)g << 16 | (uint32_t)r << 8 | b;
HsvToRgb(j + 128, 255, 255, &r, &g, &b);
array[i + 1] = (uint32_t)g << 16 | (uint32_t)r << 8 | b;
HsvToRgb(j + 64, 255, 255, &r, &g, &b);
array[i + 2] = (uint32_t)g << 16 | (uint32_t)r << 8 | b;
}
WS2812_SendDataArray(array, LED_TOTAL);
delay_us(wait * 1000);
}
}
/*********** 彩虹循环函数 ***********/
void WS2812_RainbowCycle(uint8_t wait)
{
uint32_t array[LED_TOTAL];
uint16_t i, j;
uint8_t r, g, b;
for(j = 0; j < 256 * 5; j++) // 5 cycles of all colors on wheel
{
for(i = 0; i < LED_NUM; i++)
{
HsvToRgb(((i * 256 / LED_NUM) + j) & 255, 255, 255, &r, &g, &b);
array[i * COLOR_NUM] = (uint32_t)g << 16 | (uint32_t)r << 8 | b;
HsvToRgb(((i * 256 / LED_NUM) + j + 128) & 255, 255, 255, &r, &g, &b);
array[i * COLOR_NUM + 1] = (uint32_t)g << 16 | (uint32_t)r << 8 | b;
HsvToRgb(((i * 256 / LED_NUM) + j + 64) & 255, 255, 255, &r, &g, &b);
array[i * COLOR_NUM + 2] = (uint32_t)g << 16 | (uint32_t)r << 8 | b;
}
WS2812_SendDataArray(array, LED_TOTAL);
delay_us(wait * 1000);
}
}
/*********** 彩虹跑道函数 ***********/
void WS2812_TheaterChase(uint32_t c, uint8_t wait)
{
uint32_t array[LED_TOTAL];
uint16_t i, j;
for(j = 0; j < 10; j++) // do 10 cycles of chasing
{
for(i = 0; i < LED_NUM; i += 3)
{
array[i * COLOR_NUM] = c;
array[i * COLOR_NUM + 1] = c;
array[i * COLOR_NUM + 2] = c;
}
WS2812_SendDataArray(array, LED_TOTAL);
delay_us(wait * 1000);
for(i = 0; i < LED_NUM; i += 3)
{
array[i * COLOR_NUM] = 0;
array[i * COLOR_NUM + 1] = 0;
array[i * COLOR_NUM + 2] = 0;
}
WS2812_SendDataArray(array, LED_TOTAL);
}
}
/*********** HSV转RGB函数 ***********/
void HsvToRgb(uint16_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g, uint8_t *b)
{
uint8_t region, remainder, p, q, t;
if(s == 0)
{
*r = v;
*g = v;
*b = v;
return;
}
region = h / 43;
remainder = (h - (region * 43)) * 6;
p = (v * (255 - s)) >> 8;
q = (v * (255 - ((s * remainder) >> 8))) >> 8;
t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
switch(region)
{
case 0:
*r = v;
*g = t;
*b = p;
break;
case 1:
*r = q;
*g = v;
*b = p;
break;
case 2:
*r = p;
*g = v;
*b = t;
break;
case 3:
*r = p;
*g = q;
*b = v;
break;
case 4:
*r = t;
*g = p;
*b = v;
break;
default:
*r = v;
*g = p;
*b = q;
break;
}
}
```
由于代码较长,注释也比较详细,这里就不做过多解释了。
阅读全文