1、准备材料

开发板(STM32F407G-DISC1

ST-LINK/V2驱动

STM32CubeMX软件(Version 6.10.0

keil µVision5 IDE(MDK-Arm

逻辑分析仪nanoDLA

2、实验目标

使用STM32CubeMX软件配置STM32F407通用定时器生成可变占空比PWM波形,并将其输出到LED灯引脚实现呼吸灯效果

3、实验流程

3.0、前提知识

STM32F407有10个通用定时器,其中TIM2、TIM3、TIM4和TIM5有4个捕获/比较通道,TIM9、TIM12两个定时器有2个捕获/比较通道,剩下的TIM10、TIM11、TIM13和TIM14只有一个捕获/比较通道,只有一个捕获/比较通道的通用定时器在CubeMX配置页面无“Slave Mode”和“Trigger Source”的选项,也不能联合通道,相较于拥有多个捕获/比较通道的定时器较为简单,这10个通用定时器具体特性如下表所示(注释1)

对于通用定时器来说,其每个通道均可以实现①输入捕获、②输出比较、③PWM波生成三种功能,接下来我将分三个实验来分别介绍通用定时器的这三个功能,本小节只介绍通用定时器如何生成PWM波

在“GPIO输出-点亮LED灯”小节我们介绍了如何使用GPIO输出点亮开发板上的LED灯,从而知道了开发板上控制LED灯的四个引脚分别为PD12、PD13、PD14和PD15,这四个引脚刚好可以配置为通用定时器TIM4的四个输出通道,因此接下来我们将配置这四个引脚为通用定时器TIM4的4个通道的PWM输出引脚

3.1、CubeMX相关配置

请先阅读“STM32CubeMX STM32F4 HAL库 工程建立”实验3.4.1小节配置RCC和SYS

3.1.1、时钟树配置

系统时钟树配置与上一实验一致,均设置为STM32F407总线能达到的最高时钟频率,具体如下图所示

3.1.2、外设参数配置

在Pinout & Configuration页面右边芯片引脚预览Pinout view中找到LED灯的四个控制引脚PD12、PD13、PD14和PD15,依次左键单击并配置其功能为TIM4_CHx

然后在页面左侧功能分类栏目中点开Timers栏目,单击栏目下的TIM4,并将其Channel1~4全部配置为PWM Generation CHx

具体配置如下图所示

然后对启用的TIM4定时器的四个通道参数进行设置,下面对重要参数简单介绍

①PSC:该参数为时钟源预分频系数,由于TIM4时钟来源为APB1 Timer clocks (MHz),笔者这里为84MHz,因此经过8399+1=8400分频后的频率为10KHz;

②计数模式:可以选择向上、向下、中心对齐等计数方式;

③ARR:该参数决定了生成PWM的周期,这里设置为199,表示周期为20ms,注意这里周期不能太长(注释2)

④预装载自动重装:设置为Enable后,当修改ARR的值时会在下一个UEV事件生效,否则表示不适用预装载,修改其值会立即生效

⑤PWM模式选择:可以选择模式1/模式2,这两种模式区别为生成的PWM波形不一样,选择PWM模式1且向上计数时,当Pulse值<计数值ARR时此时通道输出有效状态,否则为无效状态,当选择PWM模式2时刚好与模式1相反。如下面两个PWM波形中,上图为采用PWM模式1,通道极性为高电平时产生的PWM波,下图为采用PWM模式2,通道极性为高时产生的PWM波;

⑥Pulse值:即捕获/比较寄存器CRR的值,通过设置该参数可以决定PWM的脉冲宽度,这里设置为0,因为程序中可以动态修改该参数

⑦输出比较预装载:设置为Enable后,当修改Pulse的值时会在下一个UEV事件生效,否则会立即生效

⑧通道极性:设置通道有效状态

如下图所示为具体参数设置

3.1.3、外设中断配置

在Pinout & Configuration页面左边System Core/NVIC中勾选TIM4全局中断,然后选择合适的中断优先级即可

3.2、生成代码

请先阅读“STM32CubeMX STM32F4 HAL库 工程建立”实验3.4.3小节配置Project Manager

单击页面右上角GENERATE CODE生成工程

3.2.1、外设初始化调用流程

在工程代码主函数main()中调用MX_TIM4_Init()函数对定时器TIM4计数器参数及四个 PWM通道参数进行了配置

在该MX_TIM4_Init()函数中调用了HAL_TIM_PWM_Init()对定时器PWM输出进行了初始化

然后在HAL_TIM_PWM_Init()函数中调用了HAL_TIM_PWM_MspInit()函数对TIM4时钟和中断设置/使能

如下图所示为具体的TIM4四通道PWM输出初始化调用流程

3.2.2、外设中断调用流程

勾选了TIM4的全局中断之后,在工程文件stm32f4xx_it.c中生成了TIM4全局中断服务函数TIM4_IRQHandler()

该函数调用了HAL库的定时器中断统一处理函数HAL_TIM_IRQHandler(),最终调用PWM脉宽调制完成回调函数 HAL_TIM_PWM_PulseFinishedCallback(),该函数为虚函数

如下图所示为TIM4四通道PWM输出中断调用流程

3.2.3、添加其他必要代码

在tim.c中重新实现PWM脉宽调制完成回调函数HAL_TIM_PWM_PulseFinishedCallback(),在该回调函数中实现了对四个通道PWM的占空比重新调节的目的,即重新配置参数里的Pulse,实现了从最低占空比逐渐到最大占空比然后再逐渐减少至最低占空比的无限循环,具体代码如下所示

源代码如下

uint16_t pulseWidth=0;
uint8_t dirInc=1;
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance != TIM4)
return; if(dirInc == 1)
{
pulseWidth ++;
if(pulseWidth >= 195)
{
pulseWidth = 195;
dirInc = 0;
}
}
else
{
pulseWidth --;
if(pulseWidth <= 5)
{
pulseWidth = 5;
dirInc = 1;
}
}
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, pulseWidth);
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_2, pulseWidth);
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, pulseWidth);
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4, pulseWidth);
}

最后在主函数中以中断方式启动生成PWM即可,如下所示为启动代码

4、常用函数

/*启动定时器*/
HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim)
/*停止定时器*/
HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim)
/*启动PWM输出*/
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
/*停止PWM输出*/
HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
/*以中断方式启动定时器*/
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)
/*以中断方式停止定时器*/
HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim)
/*以中断方式启动PWM输出*/
HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
/*以中断方式停止PWM输出*/
HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
/*PWM输出完毕回调函数*/
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
/*设置PWM占空比函数*/
__HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__)

5、烧录验证

5.1、具体步骤

“设置TIM4的4个通道为PWM输出 -> 配置TIM4基本参数及4个PWM通道参数 -> NVIC中勾选TIM4全局中断并设置合适中断优先级 -> 在生成的工程tim.c文件中重新实现PWM脉宽调制完成回调函数void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) -> 在回调函数中利用__HAL_TIM_SET_COMPARE(HANDLE, CHANNEL, COMPARE)宏定义设置4个通道PWM的占空比 -> 在主函数中使用HAL_TIM_Base_Start_IT(&htim4)启动定时器TIM4 -> 然后使用HAL_TIM_PWM_Start_IT(&htim4, TIM_CHANNEL_x)函数开启四个通道PWM波的输出”

5.2、实验现象

烧录程序,会发现开发板上电后四个LED灯亮度由最暗到最亮然后从最亮再到最暗循环往复,实现呼吸灯的效果

使用逻辑分析仪监测TIM4的四个通道输出引脚状态,可以看出TIM4的四个通道输出的PWM波型周期均为20ms,并且占空比不断地在发生变化

6、注释详解

注释1:图片来源STM32Cube高效开发教程(基础篇)9.1小节

注释2:这里的周期设置为20ms,也即频率为50Hz,人眼睛对于80Hz以上刷新频率完全没有闪烁感,因此如果你实现LED呼吸灯效果有闪烁情况的话,频率不能设置的太低

更多内容请浏览 OSnotes的CSDN博客

STM32CubeMX教程6 TIM 通用定时器 - 生成PWM波的更多相关文章

  1. STM32F103定时器输出PWM波控制直流电机

    这个暑假没有回家,在学校准备九月份的电子设计竞赛.今天想给大家分享一下STM32高级定时器输出PWM波驱动直流电机的问题.. 要想用定时器输出的PWM控制直流电机,,首先要理解“通道”的概念..一个定 ...

  2. TIM—高级定时器输出PWM

    高级定时器输出PWM 主频144M,生成一个频率为1K,占空比为30%的PWM详细代码参考EVT例程PWM_Output 重要参数说明 TIM_TimeBaseInitStructure.TIM_Pe ...

  3. stm32cube--通用定时器--产生pwm波

    看了通用定时器的资料,发现内容挺多,挺难看懂,现在还是先掌握使用方法,以后再多看几遍吧. ① ② ③生成mdk工程后,在main.c的while(1)前面加上HAL_TIM_PWM_Start(&am ...

  4. 案例 高级定时器和通用定时器产生pwm的区别 gd32和stm32

  5. 第32章 TIM—高级定时器—零死角玩转STM32-F429系列

    第32章     TIM—高级定时器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...

  6. STM32通用定时器(转载)

    STM32的定时器功能很强大,学习起来也很费劲儿. 其实手册讲的还是挺全面的,只是无奈TIMER的功能太复杂,所以显得手册很难懂,我就是通过这样看手册:while(!SUCCESS){看手册-}才搞明 ...

  7. (五)转载:通用定时器PWM输出

    1.     TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有 ...

  8. STM32(7)——通用定时器PWM输出

    1.TIMER输出PWM基本概念         脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种 ...

  9. stm32之通用定时器TIM

    STM32系列的CPU,有多达8个定时器: 1.其中TMI1和TIM8是能够产生三对PWM互补输出的高级定时器,常用于三相电机的驱动:它们的时钟有APB2的输出产生: 2.其它6个为普通定时器,时钟由 ...

  10. 第31章 TIM—基本定时器—零死角玩转STM32-F429系列

    第31章     TIM—基本定时器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...

随机推荐

  1. Record - Dec. 1st, 2020 - Exam. REC

    Prob. 1 Desc. & Link. 行走的形式是比较自由的,因为只要走到了最优答案处就可以不管了,所以不需要考虑游戏的结束. 考虑二分答案. 然后预处理出每个节点到 \(s\)(另一棵 ...

  2. destoon运行流程二次开发必看

    <?php 代码首先包含common.inc.php文件 在common.inc.php文件中,首先定义常量. define('IN_DESTOON', true); define('IN_AD ...

  3. 其它——Redis与Mysql双写一致性方案解析

    文章目录 一 前言 二 一致性方案 三 先更新数据库,再更新缓存 四 先删缓存,再更新数据库 五 先更新数据库,再删缓存 一 前言 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用.在读取 ...

  4. CSE 2023 混合年度回声周末

    CSE 2023 混合年度回声周末(2023 年 4 月 13 日至 15 日)25 周年银周年纪念版 近 900 名参与者参加.又是成功的伟大一年.明年 2024 年 4 月在多伦多见.敬请关注全年 ...

  5. 基于GPS定位和人脸识别的作业识别管理系统

    一.技术参数 mysql5.5 asp.net jquery 高德地图api 百度人脸识别api 二.功能简介 实现简单的施工项目管理,包括项目地点,工期,名称,编号等 实现作业人员的档案信息管理,包 ...

  6. C#怎样链接mysql数据库

    C#一般链接sqlserver数据库,当然也会链接oracle.C#和MYSQL搭配貌似不多见哦 下面说说方法. 1.下载链接库文件,MySql.Data.dll MySql.Data.rar 2.工 ...

  7. Node.js中常用的设计模式有哪些?

    本文由葡萄城技术团队首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 设计模式简介 设计模式是由经验丰富的程序员在日积月累中抽象出的用以解决通用问题的可 ...

  8. 你也许不再需要使用 CSS Media Queries(媒体查询)了

    你也许不再需要使用 CSS Media Queries(媒体查询)了 最近,CSS 引入了一项新功能:Container Queries.它可以替代 Media Queries 并实现 Media Q ...

  9. P9580 「Cfz Round 1」Wqs Game 题解

    题目链接 挺好的博弈论题,这是一个跟官方题解不太一样的做法. 遇到这种组合游戏可以先考虑逆推胜负,把握一下规律,我们先从一个区间的胜负判断开始入手. 考察区间中最后一个数字的从属关系,如果它属于弈,因 ...

  10. JVM SandBox 的技术原理与应用分析

    https://www.infoq.cn/article/tsy4lgjvsfweuxebw*gp https://blog.csdn.net/qq_40378034/article/details/ ...