1、使用STM32F103RCT6正点原子的mini开发板控制不同颜色的幻彩灯亮,实现的效果如下:
2、幻彩灯带介绍
WS2812幻彩灯带有三条接线,5V、GND和控制信号线,利用单片机的SPI引脚可以发出不同频率协议的脉冲即可实现对幻彩灯带的各个灯珠的颜色和亮灭的控制。
本实验幻彩灯购买链接:(1米长度)
3、幻彩灯带使用STM32单片机的硬件SPI+DMA实现驱动,具体cubeMX配置见文章:
基于cubeMX的STM32开启SPI及DMA_stm32cubemx spi dma-CSDN博客
具体电路连接为:幻彩灯带线有白色的接5V,中间信号线接SPI通信线的MOSI即PB5引脚,最后一条线接GND。
WS2812幻彩灯带驱动代码如下:
(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)main函数中的调用
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_SPI1_Init();
/* USER CODE BEGIN 2 */
// RGB_BLACK(24);
// HAL_Delay(100);
// RGB_WHITE(20);
// HAL_Delay(100);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
// RGB_BLACK(60);
//HAL_Delay(500);
RGB_WHITE(60); //控制第1-60个灯珠全白
HAL_Delay(500);
RGB_YELLOW(59);//控制第1-59个灯珠全黄
HAL_Delay(500);
RGB_BLUE(58);//控制第1-58个灯珠全蓝
HAL_Delay(500);
RGB_GREEN(57);//控制第1-57个灯珠全绿
HAL_Delay(500);
RGB_RED(56);//控制第1-56个灯珠全红
HAL_Delay(500);
}
/* USER CODE END 3 */
}
3、程序源码工程下载