STM32 HAL SPI DMA驱动RGB灯(XL-5050RGBC-WS2812B)学习笔记

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博客

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

桂北研猛男

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

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

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

打赏作者

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

抵扣说明:

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

余额充值