通过SPI+DMA控制WS2812

通过SPI+DMA控制WS2812

一、STM32CubeMX配置

1、在Clion 中新建项目并,并给其项目命名,然后选中STM32CubeMX,最后点击Create

0

2、打开STM32CuMX搜索其对应的芯片型号

1

3、选择HSE使用外部晶振

3

4、打开SYS选择SW

在这里插入图片描述

5、打开Clock Configuration进行配置

在这里插入图片描述

6、给工程命名,(注使用Clion的朋友们,这个工程名一定要和最开始在Clion中创建的要一致,并且在Toolchain/IDE中选择STM32CubeIDE,最后要注意工程位置),而使用KEIL的朋友在Toolchain/IDE中选择MDK-ARM即可

在这里插入图片描述

7、在Code Generator勾上第一个,这样使得各个部分的初始化生成在对于的.c和.h文件,否则会将其初始化全部生成在main.c文件中

7

8、配置SPI,具体如图,频率选择看SPI频率选择

在这里插入图片描述

9、配置DMA,具体如图

在这里插入图片描述

10、最后点击GENERATE COOD

在这里插入图片描述

二、SPI频率选择

0码和1码

T0H0码,高电平时间0.40us 加减150ns
T1H1码,高电平时间0.85us 加减150ns
T0L0码,低电平时间0.85us 加减150ns
T1L1码,低电平时间0.40us 加减150ns
RES帧单位,低电平时间50us以上

不管是 0 码 还是 1 码 ,其时间都约等于1.25u(0.40us.+0.85=1.25us),我们选择SPI发生8位,则1.25u / 8=0.15625us,即每一位等于0.15625us

频率=1/周期

频率=1/0.15625us=6.4M

即SPI频率设置为6.4M,

但是0.4us和0.85us都可以加减0.15us

故频率可以在1/[(1.25-0.3)/8]=8.4M,1/[(1.25+0.3)/8]=5.2M之间都可以,当然越接近6.4越好

因此我们在时钟树选择48MHz,得到SPI发送频率为6M,比较接近6.4M

三、程序设计

1、c文件代码如下

#include "ws2812.h"#define    LED_NUMS   56//灯的数量#define CODE1  0xf0//1码
#define CODE0  0xc0//0码uint8_t BLACK[3] = { 0,0,0};
uint8_t RED[3]   = {30,0,0};
uint8_t GREEN[3] = {0,30,0};
uint8_t BLUE[3]  = {0,0,30};
uint8_t LED_BUFFER[24*LED_NUMS + 10];extern SPI_HandleTypeDef hspi1;//单个LED颜色设置,即将单个灯的颜色转换成对应的0码和1码
void RGB_Set_Color(uint8_t ID,uint8_t color[3])
{int i=0;for (i = 0; i < 8; i++) { //greenLED_BUFFER[ID*24+i] = ((color[1] << i) & 0x80) ? CODE1 : CODE0;}for (i = 0; i < 8; i++) { //redLED_BUFFER[ID*24+8+i] = ((color[0] << i) & 0x80) ? CODE1 : CODE0;}for (i = 0; i < 8; i++) { //blueLED_BUFFER[ID*24+16+i] = ((color[2] << i) & 0x80) ? CODE1 : CODE0;}
}//SPI_DMA发送
void RGB_Reflash(uint8_t reflash_num)
{HAL_SPI_Transmit_DMA(&hspi1, LED_BUFFER, 24*reflash_num);
}//全部黑色,可用于初始化将其所有灯熄灭
void RGB_BLACK(uint8_t RGB_LEN)
{for(int i=0;i<RGB_LEN;i++){RGB_Set_Color(i,BLACK);RGB_Reflash(RGB_LEN);}
}
//全部红色
void RGB_RED(uint8_t RGB_LEN)
{for(int i=0;i<RGB_LEN;i++){RGB_Set_Color(i,RED);RGB_Reflash(RGB_LEN);}
}
//全部绿色
void RGB_GREEN(uint8_t RGB_LEN)
{for(int i=0;i<RGB_LEN;i++){RGB_Set_Color(i,GREEN);RGB_Reflash(RGB_LEN);}
}
//全部蓝色
void RGB_BLUE(uint8_t RGB_LEN)
{for(int i=0;i<RGB_LEN;i++){RGB_Set_Color(i,BLUE);RGB_Reflash(RGB_LEN);}
}//渐变
void ws2812_1(uint16_t RGB_LEN,int speed,float light)
{if(light==0)light=1;for(int j=0;j<12;j++)//A{uint8_t My_color[3]={32/light ,3*j/light  ,  0};RGB_Set_Color(j,My_color);}for(int j=12;j<20;j++)//B{uint8_t My_color[3]={(32-4*(j-12))/light ,32/light  ,  0};RGB_Set_Color(j,My_color);}for(int j=20;j<28;j++)//C{uint8_t My_color[3]={0 ,32/light  ,  4*(j-20)/light};RGB_Set_Color(j,My_color);}for(int j=28;j<36;j++)//D{uint8_t My_color[3]={0 ,(32-4*(j-28))/light  ,  32/light};RGB_Set_Color(j,My_color);}for(int j=36;j<46;j++)//E{uint8_t My_color[3]={3*(j-36)/light ,0  ,  30/light};RGB_Set_Color(j,My_color);}for(int j=46;j<56;j++)//F{uint8_t My_color[3]={30/light ,0  ,  30-3*(j-46)/light};RGB_Set_Color(j,My_color);}uint8_t My_color[3]={ 0 ,30/light  , 0 };RGB_Set_Color(LED_NUMS,My_color);RGB_Reflash(RGB_LEN);HAL_Delay (speed);
}

2、h文件代码如下

#ifndef __WS2812_H__
#define __WS2812_H__
#include "spi.h"#ifdef __cplusplus
extern "C" {
#endif
//单个LED颜色设置,即将单个灯的颜色转换成对应的0码和1码
void RGB_Set_Color(uint8_t ID,uint8_t color[3]);void RGB_Reflash(uint8_t reflash_num);//SPI_DMA发送void RGB_BLACK(uint8_t RGB_LEN);//全部黑色,可用于初始化将其全部熄灭
void RGB_RED(uint8_t RGB_LEN);  //全部红色
void RGB_GREEN(uint8_t RGB_LEN);//全部绿色
void RGB_BLUE(uint8_t RGB_LEN); //全部蓝色//渐变light=[0.12,8]  light通过比例来调节亮度
void ws2812_1(uint16_t RGB_LEN, int speed,float light);

3、在main中调用函数 ws2812_1(56,100,1);即可,最终效果如图
在这里插入图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部