0、连接引脚
1、CubeMX配置
2、驱动代码
WS2812B.C
#include "RGB.h"
volatile uint8_t RGB_BIT_Buffer[RGB_BIT];
volatile uint8_t buffer[RGB_BIT * LED_NUMS];
volatile LEDType LED[LED_NUMS];
//搞一个数组轮流播放吧
uint32_t RGB_ST[14]=
{
0xFF0000,
0xFF7F00,
0xFFFF00,
0x7FFF00,
0x00FF00,
0x00FF7F,
0x00FFFF,
0x007FFF,
0x0000FF,
0x7F00FF,
0xFF00FF,
0xFF007F,
0xFFFFFF,
0x000000
};
/**
cook the whole buffer made by many(16 pieces) RGB_BIT_Buffers.
*/
//static void WS2812_MakeBuffer(void)
//{
// for(uint16_t i = 0; i < LED_NUMS; i++)
// {
// WS2812_CreatData(LED[i].R, LED[i].G, LED[i].B);
// memcpy(( int*)buffer + i * RGB_BIT,(const int*) RGB_BIT_Buffer, RGB_BIT);
// }
//}
void WS2812_Update(void)
{
HAL_SPI_Transmit_DMA(&hspi2,(uint8_t *)buffer, RGB_BIT * LED_NUMS);
// HAL_SPI_Transmit(&hspi2, (uint8_t *)buffer, RGB_BIT * LED_NUMS,200);
}
/**
create 24 byte sent by SPI using RGB values.
*/
static void WS2812_CreatData(uint8_t R, uint8_t G, uint8_t B)
{
uint8_t temp[RGB_BIT] = {0};
for (uint8_t i = 0; i < 8; i++)
{
temp[7 - i] = (G & 0x01) ? WS2812_1 : WS2812_0;
G = G >> 1;
}
for (uint8_t i = 0; i < 8; i++)
{
temp[15 - i] = (R & 0x01) ? WS2812_1 : WS2812_0;
R = R >> 1;
}
for (uint8_t i = 0; i < 8; i++)
{
temp[23 - i] = (B & 0x01) ? WS2812_1 : WS2812_0;
B = B >> 1;
}
memcpy((int *)RGB_BIT_Buffer, temp, RGB_BIT);
}
void WS2812_TurnOff(void)
{
for(uint16_t i = 0; i < LED_NUMS * 24; i++)
{
buffer[i] = WS2812_0;
}
}
/**
一个位置的led会因颜色值而明亮
pos is [0 , max-1]
*/
void WS2812_Color_Pos(uint32_t color, uint16_t Pos)
{
uint8_t R, G, B;
R = (color >> 16 ) & 0x00FF;
G = (color >> 8 ) & 0x0000FF;
B = (color ) & 0x0000FF;
WS2812_CreatData(R, G, B);
if(Pos < LED_NUMS && Pos > 0)
{
memcpy(( int*)buffer + RGB_BIT * Pos,(const int*)RGB_BIT_Buffer, RGB_BIT);
}
else
{
WS2812_TurnOff();
}
}
void WS2812_Show_Wheel(void)
{
static uint16_t i = 0;
i++;
WS2812_Color_Pos(0xFF0000, (i) % 16);//红色
WS2812_Color_Pos(0XFF7F00, (i + 1) % 16);
WS2812_Color_Pos(0XFFFF00, (i + 2) % 16);
WS2812_Color_Pos(0X7FFF00, (i + 3) % 16);
WS2812_Color_Pos(0X00FF00, (i + 4) % 16);
WS2812_Color_Pos(0X00FF7F, (i + 5) % 16);
WS2812_Color_Pos(0X00FFFF, (i + 6) % 16);
WS2812_Color_Pos(0X007FFF, (i + 7) % 16);
WS2812_Color_Pos(0X0000FF, (i + 8) % 16);
WS2812_Color_Pos(0X7F00FF, (i + 9) % 16);
WS2812_Color_Pos(0XFF00FF, (i + 10) % 16);
WS2812_Color_Pos(0XFF007F, (i + 11) % 16);
WS2812_Color_Pos(0XFF0000, (i + 12) % 16);
WS2812_Color_Pos(0XFF7F00, (i + 13) % 16);
WS2812_Color_Pos(0XFFFF00, (i + 14) % 16);
WS2812_Color_Pos(0X7FFF00, (i + 15) % 16);//绿色
WS2812_Update();
}
WS2812B.H
#ifndef __RGB_H__
#define __RGB_H__
#include "string.h"
#include "main.h"
#include "spi.h"
#define WS2812_0 0xC0
#define WS2812_1 0xF0
#define WS2812_RST 0x00
#define LED_NUMS 16
#define RGB_BIT 24
//以下编码准寻· 光学色相环(RGB模型)-12色
#define red_0 0xFF0000 //红
#define brown_30 0xFF7F00 //棕色
#define yellow_60 0xFFFF00 //黄色
#define Dark_green_90 0x7FFF00 //深绿色
#define Medium_green_120 0x00FF00 //中绿色
#define Light_green_150 0x00FF7F //浅绿色
#define Baby_blue_180 0x00FFFF //浅蓝色
#define Medium_blue_210 0x007FFF //中蓝色
#define Dark_blue_240 0x0000FF //深蓝色
#define modena_270 0x7F00FF //深紫色
#define Medium_purple_300 0xFF00FF //中紫色
#define lilac_330 0xFF007F //浅紫色
#define white_360 0xFFFFFF //白色
#define off_390 0x000000 //熄灯
extern uint32_t RGB_ST[14];
typedef struct
{
uint8_t R;
uint8_t G;
uint8_t B;
} LEDType;
extern volatile uint8_t RGB_BIT_Buffer[RGB_BIT];
extern volatile uint8_t buffer[RGB_BIT * LED_NUMS];
extern volatile LEDType LED[LED_NUMS];
/**
turn off all leds
*/
void WS2812_TurnOff(void);
void WS2812_Show_Wheel(void);
void WS2812_Update(void);
static void WS2812_MakeBuffer(void);
static void WS2812_CreatData(uint8_t R, uint8_t G, uint8_t B);
void WS2812_Color_Pos(uint32_t color, uint16_t Pos);
#endif
main.c
__IO uint32_t RGB_delay=0;
uint8_t x=0;
void RGB_Process(void)//颜色轮询
{
if(uwTick-RGB_delay < 1000) return;
RGB_delay=uwTick;
x =(x+1)%15;
WS2812_Color_Pos(RGB_ST[x], 1);
WS2812_Update();
}
控制RGB色号的编码如图:
本文章学习自:【STM32】硬件SPI+DMA驱动WS2812灯珠,基于HAL库_stm32 ws2812-CSDN博客