【基于 STM32CubeMX + PWM + DMA驱动SW2812b全彩RGB灯】

STM32CubeMX配置:

  1. 勾选烧录脚在这里插入图片描述
  2. 配置高速外部时钟在这里插入图片描述
  3. 选择PWM通道和引脚在这里插入图片描述
  4. 配置DMA:在这里插入图片描述
  5. 定时器周期配置:在这里插入图片描述
  6. 时钟树配置(最好是配置单片机最大时钟):在这里插入图片描述
  7. 添加工程文件以及名字生成cubeMX工程。

工程源码:

rgb.c文件

#include "rgb.h"
#include "main.h"
#include "tim.h"

#define ONE_PULSE        (40)                           //1 码
#define ZERO_PULSE       (20)                           //0 码
#define RESET_PULSE      (60)                           //80 ,复位信号
#define LED_NUMS         (10)                            //led 数量
#define LED_DATA_LEN     (24)                           //led 长度,单个需要24bits
#define WS2812_DATA_LEN  (LED_NUMS*LED_DATA_LEN)        //ws2812灯条需要的数组长度

//uint16_t static RGB_buffur[RESET_PULSE + WS2812_DATA_LEN] = { 0 };

uint16_t  RGB_buffur[RESET_PULSE + WS2812_DATA_LEN] = { 0 };

void ws2812_set_RGB(uint8_t R, uint8_t G, uint8_t B, uint16_t num)
{
    //
    uint16_t* p = (RGB_buffur + RESET_PULSE) + (num * LED_DATA_LEN);
    
    for (uint16_t i = 0;i < 8;i++)
    {
        //
        p[i]      = (G << i) & (0x80)?ONE_PULSE:ZERO_PULSE;
        p[i + 8]  = (R << i) & (0x80)?ONE_PULSE:ZERO_PULSE;
        p[i + 16] = (B << i) & (0x80)?ONE_PULSE:ZERO_PULSE;
    }
}
/*ws2812 初始化*/
void ws2812_init(uint8_t led_nums)
{
	uint16_t num_data;
	num_data = 60 + led_nums * 24;
	for(uint8_t i = 0; i < led_nums; i++)
	{
		ws2812_set_RGB(0x00, 0x00, 0x00, i);
	}
	 HAL_TIM_PWM_Start_DMA(&htim3,TIM_CHANNEL_3,(uint32_t *)RGB_buffur,(num_data)); 
}


/*全亮蓝灯*/
void ws2812_blue(uint8_t led_nums)
{
	uint16_t num_data;
	num_data = 60 + led_nums * 24;
	for(uint8_t i = 0; i < led_nums; i++)
	{
		ws2812_set_RGB(0x00, 0x00, 0x22, i);
	}
	 HAL_TIM_PWM_Start_DMA(&htim3,TIM_CHANNEL_3,(uint32_t *)RGB_buffur,(num_data));
}
/*全亮红灯*/
void ws2812_red(uint8_t led_nums)
{
	uint16_t num_data;
	num_data = 60 + led_nums * 24;
	for(uint8_t i = 0; i < led_nums; i++)
	{
		ws2812_set_RGB(0x22, 0x00, 0x00, i);
	}
	 HAL_TIM_PWM_Start_DMA(&htim3,TIM_CHANNEL_3,(uint32_t *)RGB_buffur,(num_data));
}
/*全亮绿灯*/
void ws2812_green(uint8_t led_nums)
{
	uint16_t num_data;
	num_data = 60 + led_nums * 24;
	for(uint8_t i = 0; i < led_nums; i++)
	{
		ws2812_set_RGB(0x00, 0x22, 0x00, i);
	}
	 HAL_TIM_PWM_Start_DMA(&htim3,TIM_CHANNEL_3,(uint32_t *)RGB_buffur,(num_data));
}

void ws2812_example(void)
{		
	ws2812_set_RGB(0x00, 0x00, 0x22, 0);
    ws2812_set_RGB(0x00, 0x00, 0x22, 1);
    ws2812_set_RGB(0x00, 0x00, 0x22, 2);
    ws2812_set_RGB(0x00, 0x00, 0x22, 3);
    ws2812_set_RGB(0x00, 0x00, 0x22, 6);
    ws2812_set_RGB(0x00, 0x00, 0x22, 7);
//	ws2812_set_RGB(0x00, 0x00, 0x22, 8);
//    ws2812_set_RGB(0x00, 0x00, 0x22, 10);
    HAL_TIM_PWM_Start_DMA(&htim3,TIM_CHANNEL_3,(uint32_t *)RGB_buffur,(60 + 10 * 24)); //344 = 80 + 24 * LED_NUMS(11)

    HAL_Delay(500);
}

rgb.h文件

#ifndef _RGB_H_
#define _RGB_H_

#include "main.h"
#include "stdint.h"
#include "type.h"

void ws2812_set_RGB(uint8_t R, uint8_t G, uint8_t B, uint16_t num);

void ws2812_example(void);
extern void ws2812_blue(uint8_t led_nums);
extern void ws2812_red(uint8_t led_nums);
extern void ws2812_green(uint8_t led_nums);
void ws2812_init(uint8_t led_nums);
#endif

time.c 文件中存放DMA数据传送完成回调函数:

/* USER CODE BEGIN 1 */

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    HAL_TIM_PWM_Stop_DMA(&htim3,TIM_CHANNEL_3);
}

/* USER CODE END 1 */

type.h 类型名的重命名文件

#ifndef _TYPE_H_
#define _TYPE_H_

#include "main.h"
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdbool.h>


typedef uint8_t 	u8;
typedef uint16_t 	u16;
typedef uint32_t 	u32;

typedef int8_t 		s8;
typedef int16_t 	s16;
typedef int32_t		s32;

typedef volatile uint8_t 	vu8;
typedef volatile uint16_t 	vu16;
typedef volatile uint32_t 	vu32;

typedef volatile int8_t 	vs8;
typedef volatile int16_t 	vs16;
typedef volatile int32_t	vs32;

typedef union{
	s8 		s8_fmt[8];	//for angle and omega
	u8 		u8_fmt[8];	//for angle and omega
	char 	ch_fmt[8];	//
	s16		s16_fmt[4];
	u16		u16_fmt[4];
	s32 	s32_fmt[2];
	u32 	u32_fmt[2];
	float 	f32_fmt[2];
	double 	d64_fmt;
}data_convert_ut;	//for diaobi gyro


#endif

main.c 文件的编写:

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_USART1_UART_Init();
  MX_USART2_UART_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */

//HAL_TIM_PWM_Start_DMA(&htim3,TIM_CHANNEL_3,(uint32_t *)RGB_buffur,(num_data)); 
è®¾ç½®é»˜è®¤çš„å ç©ºæ¯”å€?
//__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_3,40);

//        WS2812_Display_2( 22 , 0 , 0, 0);
//        WS2812_Display_2(  0 , 22, 0, 1);
//        WS2812_Display_2(  0 , 0, 22, 2);
//        WS2812_Display_2( 255, 0 , 255, 3);
//	HAL_TIM_PWM_Start_DMA(&htim3,TIM_CHANNEL_3,(uint32_t *)RGB_buffur,(176));//启动DMAä¼ è¾“
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

	ws2812_init(10);// 所有RGB小灯的初始化   --- 10个
	
	uint16_t num_data;
	num_data = 60 + 10 * 24;
	for(uint8_t i = 0; i < 10; i++)
	{
		ws2812_set_RGB(0x50, 0x50, 0x50, i);//0x50 小灯最亮
	}
	 HAL_TIM_PWM_Start_DMA(&htim3,TIM_CHANNEL_3,(uint32_t *)RGB_buffur,(num_data));
	
  while (1)
  {
  
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

END 以上就是相关配置,最需要注意的就是时钟以及pre数值以及芯片时钟频率的设置,还有DMA外设地址通道等配置。

  • 5
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值