关于STM32利用TIM+PWM+DMA控制WS2812

这篇具有很好参考价值的文章主要介绍了关于STM32利用TIM+PWM+DMA控制WS2812。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

开发环境

MCU:STM32F103c8t6
开发工具:STM32CubeMX

 使用板子参考原理图:STM32F103C8T6最小系统板开源链接

PWM

脉宽调制(PWM)基本原理:控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等但宽度不一致的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使各脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各脉冲的宽度进行调制,既可改变逆变电路输出电压的大小,也可改变输出频率 。

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

通过数据手册我们可以看到TIM2,TIM3,TIM4(通用定时器)挂载在APB2总线上,每个通用定时器都有独立的4个通道可以用来作为:输入捕获、输出比较、PWM输出、单脉冲模式输出等。

那么直接上STM32CUBEMX

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

 这边选用了PB9作为TIM4_CH4通道用来做PWM输出(上述勾选去掉)

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

 也就是外部时钟TCLK=72mhz

同时引进定时器的原理 向上计数模式UP

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

 ARR就是自动重装载值hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

 CCRX为捕获/比较寄存器值

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

 CNT为计数器当前值

那么其中的逻辑是这样的

  • 当CNT小于CCRx时,TIMx_CHx通道输出设置的电平;
  • 当CNT等于或大于CCRx时,TIMx_CHx通道输出与设置相反的电平。

 设置的电平

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

那么我们直接配置好

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm中加入使能代码

HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4);

看下示波器效果

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

看的出来是低电平20% 高电平80% 频率2KHZ

那么是怎么配置出来的呢

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

看图可得出以下数据:

PSC=71

向上计数模式

ARR=499

>>>>>>

PWM 模式1

CCRX=100

>>>>>>

通道输出极性低电平

好的,我们得到这么多数据,还需要记住一些公式

Fpwm=TCLK/(ARR+1)*(PSC+1) =2000HZ

占空比=CCRX/(ARR+1)=100/(499+1)=20%

改CCR1可以修改占空比,修改arr可以修改频率

好的,这样简单的PWM配置就完成了,接下来模拟时序

WS2812时序讲解具体在这个博客,看完再跳回本页面

1码 2/3高电平 1/3低电平

0码 1/3高电平 2/3低电平

一个码的周期是1.25us,也就是800khz

无聊写了个代码,算对应的PSC和ARR

计算 定时器arr和psc

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

随便选一组,怎么方便怎么来

选PSC=1,ARR=44,ch polarity high.

波形符合理论

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

 引入新的方式:直接修改CCRx寄存器的值

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

htim4.Instance->CCR4 = 30

DMA

进入正题 TIM+DMA配置

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

 hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

(HAL_TIM_PWM_PulseFinishedCallback() 是一个回调函数,当DMA传输完成以后,就会调用这个函数,由于本文DMA传输模式选择为Circular,所以DMA需要手动关闭,否则DMA会不断的搬运数据。)

DMA传输位宽和定义的缓冲区位宽要一致

u32 对word

u16 对half word

u8  对 byte

hal_tim_pwm_start_dma,STM32,stm32,单片机,arm

然后生成文件,打开工程

新建一个 NEW GROUP

创建WS2812.h   WS2812.c文件 

#ifndef _WS2812_H
#define _WS2812_H
#endif
//标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线
//头文件区
#include "main.h"
#include "dma.h"
#include "tim.h"


//用户修改参数区
#define ONE_PULSE        (59)                           //1 码计数个数
#define ZERO_PULSE       (29)                           //0 码计数个数
#define RESET_PULSE      (48)                           //80 复位电平个数(不能低于40)
#define LED_NUMS         (4)                            //led 个数
#define LED_DATA_LEN     (24)                           //led 长度,单个需要24个字节
#define WS2812_DATA_LEN  (LED_NUMS*LED_DATA_LEN)        //ws2812灯条需要的数组长度



void ws2812_set_RGB(uint8_t R, uint8_t G, uint8_t B, uint16_t num);//设置彩灯颜色
void ws2812_example(void);
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim);


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

WS2812_DATA_LEN ==(LED_NUMS*LED_DATA_LEN)

测试用的LED_NUMS=4,那么数组长度为4*24+reset_pulse       

reset_pulse>=40

(DMA 每一个定时器周期就搬运一个0到定时器CCR中,定时器将产生一个1.25us的全低电平,40个为50us,这个50us的低电平作为ws2812的复位信号。)

#include "WS2812.h"


 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)
{
    //指针偏移:需要跳过复位信号的N个0
    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;
    }

}

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
//    HAL_TIM_PWM_Stop_DMA(&htim4,TIM_CHANNEL_4);
//    HAL_TIM_PWM_Stop_DMA(&htim1,TIM_CHANNEL_1);
	HAL_TIM_PWM_Stop_DMA(&htim4,TIM_CHANNEL_3);//PA8
}

void ws2812_example(void)
{
    //#1.填充数组
    ws2812_set_RGB(0x22, 0x00, 0x00, 0);
    ws2812_set_RGB(0x00, 0x22, 0x00, 1);
    ws2812_set_RGB(0x00, 0x00, 0x22, 2);
    ws2812_set_RGB(0x22, 0x22, 0x22, 3);
    //#2.传输数据
//    HAL_TIM_PWM_Start_DMA(&htim4,TIM_CHANNEL_4,(uint32_t *)RGB_buffur,(176));  
//	  HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,(176));
	HAL_TIM_PWM_Start_DMA(&htim4,TIM_CHANNEL_3,(uint32_t *)RGB_buffur,(176));
    //#3.延时:使效果可以被观察
    HAL_Delay(500);
    
    ws2812_set_RGB(0x22, 0x00, 0x00, 1);
    ws2812_set_RGB(0x00, 0x22, 0x00, 2);
    ws2812_set_RGB(0x00, 0x00, 0x22, 3);
    ws2812_set_RGB(0x22, 0x22, 0x22, 0);
    
//    HAL_TIM_PWM_Start_DMA(&htim4,TIM_CHANNEL_4,(uint32_t *)RGB_buffur,(176)); 
//    HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,(176));
    HAL_TIM_PWM_Start_DMA(&htim4,TIM_CHANNEL_3,(uint32_t *)RGB_buffur,(176));	
    HAL_Delay(500);
	}

(RGB_buffur + RESET_PULSE) + (num * LED_DATA_LEN)对应得是

RGB_buffur[RESET_PULSE + num * LED_DATA_LEN]的地址(num取值这里是0-3)

实际上就是跳过最开始的数组里面的RESET_PULSE

RGB_buffur[]={ RESET_PULSE ,NUM0数据,NUM1数据,NUM2数据,NUM3数据}

在main.c文件while中加入

		ws2812_example();

实物效果图

WS2812

参考链接

关于STM32F4xx使用DMA+TIM3_PWM调试灯带WS2812过程记录文章来源地址https://www.toymoban.com/news/detail-789355.html

到了这里,关于关于STM32利用TIM+PWM+DMA控制WS2812的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32G0 定时器PWM DMA输出驱动WS2812配置 LL库

    优点:不消耗CPU资源 缺点:占用内存较大 定时器配置 定时器通道:TIM3 CH2 分频:0 重装值:79,芯片主频64Mhz,因此PWM输出频率:64Mhz/79 ≈ 800Khz,满足芯片要求。 auto-reload preload 要关闭 output compare preload 要打开 DMA配置 外设一定要选择TIM3_UP,不要选TIM_CHx 方向是内存到外设,

    2024年02月10日
    浏览(49)
  • STM32 HAL库 PWM+DMA 驱动WS2812B彩灯(STM32F030F4P6)

    博主使用STM32驱动WS2812B主要参考了这位佬的文章,因为需求问题,采用了Cortex-M0的stm32f030f4p6(16k的flash,4k的sram)来驱动,原文中写的是stm32f103c8t6,个人认为其实区别并不是很大,需要修改部分参数即可移植(cv战士申请出战)。 上图是我的一圈灯,一共8个,第一个LED的数

    2024年02月06日
    浏览(66)
  • WS2812B彩灯 STM32HAL库开发:PWM+DMA(stm32f103c8t6)

    目录 一、摘要 二、WS2812B介绍 三、CUBEMX配置 四、程序介绍(KEIL编译器) 五、数据手册         1、本文使用示例单片机型号为 stm32f103c8t6 ,RGB型号为 WS2812B ;          2、主要实现功能是实现用 PWM+DMA 使RGB_LED亮起不同颜色的灯光;         3、目的:简单调通该型号

    2024年02月03日
    浏览(49)
  • STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

    (1)编程平台:Keil5 (2)CubeMX (1)某宝买的RGB模块(4个灯珠级联) (2)F1的板子,本例使用经典F103C8T6 (3)ST-link 下载器 (4)杜邦线若干 (1)模块简介: 没什么比手册讲得更加清楚了,模块中文数据手册:ws2812b中文资料_数据手册_参数 (2)驱动原理:          以上这是数据手册中提到

    2023年04月11日
    浏览(49)
  • [HAL]STM32 SPI+DMA驱动WS2812

    该程序是纯手敲,非Cube生成!所有代码均注释。 源码在文章后面获取 Keyword: 单线通讯、归零码、Reset、RGB顺序 RGB一共有24bit位 -相当于驱动一个灯要24bit位 -驱动若干个灯要24* n bit位,通过Reset码决定数据终止(保持) 24bit位应该如何发送? 可见: 表示低电平需要 T0H和T0L的配

    2024年02月09日
    浏览(53)
  • 使用STM32F103的SPI+DMA驱动ws2812 LED

    目录 前言 一、WS2812协议 1.1 数据传输编码方式:  1.2 传输的数据结构 二、驱动方式:SPI+DMA 2.1 原理介绍 2.2 SPI+DMA操作  2.3 编写代码 2.4 使用 三 总结 参考文章 主要使用的STM32F103C8T6芯片的SPI+DMA方式实现WS2812的驱动协议,总体可以看作是使用SPI来实现一种通信协议来发送信号。

    2024年02月09日
    浏览(65)
  • 讲解STM32驱动WS281x灯珠的多种实现方式:普通IO、SPI+DMA、以及PWM+DMA驱动方法

    STM32作为一款高性能、功能丰富的单片机,其丰富的外设和强大的性能,使其在嵌入式领域得到了广泛的应用。本篇文章将介绍如何利用STM32驱动WS281x系列的LED灯珠。我们会使用三种不同的驱动方式进行实现:一种是普通IO方式驱动,一种是SPI+DMA方式驱动,最后一种是PWM+DMA方

    2024年02月11日
    浏览(40)
  • 基于stm32作品设计:多功能氛围灯、手机APP无线控制ws2812,MCU无线升级程序

    作品哔哩哔哩视频:https://www.bilibili.com/video/BV1Yb4y1a7AQ#reply5536921990 资料链接: 蓝牙彩灯v1.01资料链接: CSDN: https://download.csdn.net/download/mbs520/25149435 百度网盘: https://pan.baidu.com/s/14Vout7Q2P6JBDZCCd8Gm6w 提取码:b7it 蓝牙彩灯v1.03资料链接: https://download.csdn.net/download/mbs520/25150035 取

    2024年02月09日
    浏览(46)
  • STM32作品设计:蓝牙彩灯V1.4(WS2812全彩、声控、光控、人体红外、小科语音控制、手机APP、蓝牙无线升级)

    @ biliblil视频链接:https://www.bilibili.com/video/BV14L411V78b/ 资料可联系作者:2809786963 实物链接:https://m.tb.cn/h.5hxssok?tk=vEQCWYHTKs0 CZ0001 1、手机APP控制亮度、颜色 2、多种显示模式:闪烁、渐变、呼吸、流水 3、拾音灯模式(随音起舞) 4、手机设置:光控模式、声控模式、声光控模式

    2024年02月11日
    浏览(92)
  • ESP32(MicroPython) 网页控制环形WS2812

    ESP32(MicroPython)网页控制环形WS2812 本程序用于提供网页控制环形WS2812,为了不影响网页正常运行,本程序取消了流水灯形式,改为每个灯或每2个灯或每4个灯取随机亮度,延时和亮度可调。主控换成ESP32C3,感觉网页流畅度比ESP32-EROOM32低一些。 程序如下

    2024年02月15日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包