描述

这篇文章延续上一篇文件,上一篇介绍了WS2812的一些知识和设置,这一篇文章会利用CubeMX工具进行芯片设置,设置一个产生PWM波的管脚,用它来完成WS2812灯带的控制。

这篇文章还附赠了一个我写的.h和.c文件,可以很简单的添加到工程中,你也可以把这两个文件的代码放到main.c中,很容易。

  • 研发平台:淘宝上购买的野火店铺的一款单片机,名字叫骄阳开发板,核心芯片是
    stm32F407IGT6
  • 灯带:WS2812型号的灯带

CubeMX设置步骤

  1. 依旧是打开CubeMX工具,选择你的芯片,构建一个空的工程,这里不进行赘述
  2. 选择左侧“Timers”菜单栏,我们这里选择“TIM1”,当然了我们选择其他的定时器也可以,只要遵照芯片手册进行相应的设置即可
  3. 我们像之前控制直流电机一样,将“Clock Source”选择为“Internal Clock”内部时钟,将“Channel”选择为“PWM Generation CH1”,如下图所示
  4. 我们选择上方大菜单栏的“Clock Configuration”,将“HCLK”(MHz)设置为168,然后回车,CubeMX会自动给你设置好其他的时钟信号
  5. 我们这时去查阅一下手册,查询TIM1挂载在哪个时钟总线上。之前的文章我有过介绍,这里不提了也不放截图了,直接说结论。TIM1挂载在APB2总线上。显然现在,TIM1的频率就是168MHz了
  6. 上一篇文章我们说过,我们可以将这个PWM频率设置为800kHz,那么根据计算,我们可以这样设置:预分频系数为0,重装载值为209,这样生成的PWM波的频率就是800kHz了。我们在CubeMX完成这样的设置,如下图。
  7. 现在我们要进行一个只属于这篇文章的特殊设置了。在TIM1的“Parameter Settings”的同级菜单中,有“DMA Settings”这样一个设置。点开后,会出现如下的界面
  8. 我们点击“Add”,然后在“DMA Request”下面会出现一个“Select”的下拉框,我们点击下拉框并选择“TIM1_CH1”;我们再将鼠标点击“Direction”小菜单,将下拉框“Peripheral To Memory”改为“Memory To Peripheral”
  9. 我们接下来按照之前的方式进行接下来的工程配置(路径啊,工程名啊什么的),最后点击生成代码来生成整个工程就OK了

核心代码

ws2812.h

#ifndef __WS2812_LED_H__
#define __WS2812_LED_H__

#include "tim.h"

#define ONE_PULSE 140
#define ZERO_PULSE 70                        

#define LED_NUM 30
#define LED_DATA_LEN 24
#define RESET_PULSE_LEN 80  
#define DATA_BUFFER_LEN RESET_PULSE_LEN+(LED_DATA_LEN*LED_NUM)

uint16_t static data_buffur[DATA_BUFFER_LEN] = { 0 };

void led_init(void);
void led_on(void);
void led_set(uint8_t led_id, uint8_t value_r, uint8_t value_g, uint8_t value_b);


#endif

ws2812.c

#include "ws2812.h"

void led_init(void)
{
    for(uint8_t i = 0; i < LED_NUM; i++)
    {
        led_set(i, 0x00, 0x00, 0x00);
    }
}

void led_set(uint8_t led_id, uint8_t value_r, uint8_t value_g, uint8_t value_b)
{
    uint16_t* p = (data_buffur + RESET_PULSE_LEN) + (LED_DATA_LEN * led_id);
    for (uint16_t i = 0; i < 8; i++)
    {
            p[i]      = (value_g << i) & (0x80)? ONE_PULSE: ZERO_PULSE;
            p[i + 8]  = (value_r << i) & (0x80)? ONE_PULSE: ZERO_PULSE;
            p[i + 16] = (value_b << i) & (0x80)? ONE_PULSE: ZERO_PULSE;
    }
}

void led_on(void)
{
     HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t *)data_buffur, DATA_BUFFER_LEN);
}

代码移植

放在下一篇介绍

连接方式

将灯带的5V和GND连接到单片机上的5V和GND
将灯带的Din口,连接到单片机上的PE9管脚

为什么是PE9管脚?我们可以通过CubeMX的设置中,查阅到我们将TIM1的CH1通道的管脚,设置为了PE9。如果你使用的是其他的定时器,查阅对应的管脚,进行更改就是了。

运行结果

上述操作完全进行之后,将代码烧到单片机中,点击复位按钮。我们会发现灯带从第0号灯到第29号灯,依次亮起逐渐变化的彩虹色,并不停地循环这个过程。形成一个跑马灯的过程。

代码很简单,你可以自己改成你想要的灯带效果,这里不过多介绍。

总结

这一篇文章介绍了如何通过CubeMX设置管脚,做到控制WS2812灯带。
本篇文章贴出了源码的头文件和源文件,下面一篇文章会对这些代码进行详解。