打印
[APM32F4]

【APM32F411V Tiny Board测评】2.使用SPI+DMA驱动WS2812

[复制链接]
758|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
#申请原创#@21小跑堂 今天给大家带来的是SPI+DMA驱动WS2812,其实WS2812是一种常见的LED灯珠,通常用于制作RGB全彩LED矩阵。它由三个引脚组成:VCC(电源)、GND(接地)和数据信号。每个灯珠包含一个红色、绿色和蓝色LED,可以通过不同的顺序和亮度控制来产生千变万化的颜色。在电子电路中,WS2812模块通常通过SPI接口与微控制器连接,用于驱动和编程。
具体如何驱动时序和逻辑其实可以参考以下文章,我觉得写的非常好,这里也谢谢作者的分享,感谢@二狗正在赶来路上
https://blog.csdn.net/xia233233/ ... 1001.2014.3001.5502
我主要讲讲如何配置cubemx和移植Adafruit_NeoPixel来玩耍WS2812吧。
首先根据上次的操作,打开cubemx,选择好对应型号,其实也可以用上次的cubemx工程继续配置,这个就看个人习惯了,我是重新配置了一下。
首先进入到cubemx中要配置外部时钟晶振,这里选择外部时钟晶振。

接下来是配置SWD,主要是为了方便后续的下载与调试。

接下来是配置我们需要的SPI,本次我选择的是SPI1,然后由于需要SPI的速度在5.52——9.41MHz范围内,并且SPI发送一个字节时间长度等于一个编码的时间长度。因此,我们后续需要配置MCU的时钟树。

下面是针对SPI的DMA配置。

这是针对时钟树进行的配置,其实使用cubemx来配置APM32F11的话,主频最高让设置100MHz,不过就单独驱动WS2812的话,我觉得主频设置成72MHz也是可以的,设置成72MHz的话可以让SPI的速率达到9MHz。

以上就是外设的配置,已经操作完成,接下来就是配置输出工程方面。第一步是选择代码生成,设置如下:

主要设置了复制仅用到的库,这样是为了让工程小一些,还有就是将外围设备初始化为每个外围设备生成一对“.c/.h”文件,这样方便移植和修改。
接下来就是可以生成工程了,设置好工程名称、工程存储位置和编译链/IDE既可。

至此,针对于cubemx方面的操作就完成了,将生成的工程打开。

WS2812的C和H文件是从这里下载,https://gitee.com/xia-wang-666/ws2812_-led需要注意的是,请按照原作者的规则去使用该文件,毕竟开源不易,请大家珍惜
如果就是需要点亮WS2812的话,可以将WS2812的C和H文件放入到刚刚生成好的工程中,并配置好头文件,编译不报错,就可以使用了。如果想要测试代码是否OK,可以在主函数调用以下函数中的一个/多个均可。其中LEN是代表要电量的LED灯个数。
//常用颜色的点亮测试函数

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_WHITE(uint16_t RGB_LEN)

{

uint8_t i;

for(i = 0; i < RGB_LEN; i++)

{

RGB_Set_Color(i, WHITE);

}

RGB_Reflash(RGB_LEN);

}

值得注意的是:以上代码如果按照此文章或者链接文章操作,均可以实现WS2812的正确驱动操作。当然了,点亮不是目的,目的是玩起来。之前有了解的是,WS2812的C语言方面的库,可以使用Adafruit_NeoPixel,AdafruitNeoPixel是一个开源的Arduino库,用于控制基于WS2811、WS2812或APA102(又称DotStar)等LED驱动芯片的RGB LED像素串。
void setAllPixelColor(uint8_t r, uint8_t g, uint8_t b)//设置所有LED的颜色

{

uint8_t i = 0;

RGB_RST();

for(i = 0; i < PIXEL_MAX; i++)

{

RGB_DAT[i].R = r;

RGB_DAT[i].G = g;

RGB_DAT[i].B = b;

}

for(i = 0; i < PIXEL_MAX; i++)

{

RGB_Reflash(i);

}

}

void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b)//设置单个LED颜色

{

uint8_t i = 0;

RGB_RST();

RGB_DAT[n].G = r;

RGB_DAT[n].R = g;

RGB_DAT[n].B = b;

for(i = 0; i < PIXEL_MAX; i++)

{

RGB_Reflash(i);

}

}

void SetPixelColor(uint16_t n, uint32_t c)

{

RGB_RST();

RGB_DAT[n].R = ((uint8_t)(c >> 16));

RGB_DAT[n].G = (uint8_t)(c >> 8);

RGB_DAT[n].B = (uint8_t)c;

RGB_Reflash(n);

}
以上代码可以放在WS2812中,PIXEL_MAX可以用RGB_NUM替代,函数的头文件我就不发了,其实就把void以及这行放到ws2812.h中既可。
void rainbowCycle(uint16_t wait)//彩虹特效,放在主函数while(1)中运行

{

uint16_t i, j;

for(j = 0; j < 256 * 5; j++)

{

// 5 cycles of all colors on wheel

for(i = 0; i < PIXEL_MAX; i++)

{

SetPixelColor(i, Wheel(((i * 256 / PIXEL_MAX) + j) & 255));

}

HAL_Delay (wait);

}

}

以下是彩虹特效,哈哈,还是很漂亮的嘛

到此,针对于WS2812的SPI+DMA驱动WS2812并且加入了一些特效效果就告一段落了,总的来说,SPI与DMA是比较常用的MCU的外设之一,本次的应用可以很由浅入深的了解SPI与DMA的工作流程,并且可以将WS2812驱动起来,实现一些灯效,在一些LED项目中具有参考意义。

使用特权

评论回复
沙发
szt1993| | 2024-5-23 17:08 | 只看该作者
WS2812模块通常通过SPI接口与微控制器连接

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:嵌入式技术专家
简介:擅长电路设计、物联网产品开发、射频产品开发,喜欢打篮球,技术交流,欢迎各位来聊~

628

主题

2603

帖子

5

粉丝