《STM32单片机开发应用教程(HAL库版)—基于国信长天嵌入式竞赛实训平台(CT117E-M4)》第四章4.8 TIM---PWM输出实验

2023-11-14

写在前面——
《STM32单片机开发应用教程(HAL库版)—基于国信长天嵌入式竞赛实训平台(CT117E-M4)》第四章4.8 TIM—PWM输出实验,讲解TIM 定时与PWM输出的STM32CubeMX配置和程序设计方法
官方例程下载:https://pan.baidu.com/s/1QC5BnDgY1m1me6-ihQ_OUQ?pwd=nqb1
提取码:nqb1

4.8 TIM—PWM输出实验

4.8.1. 实验任务

  1. TIM定时作用:参考官方例程HAL_10_TIM_BASE,实现流水灯。
  2. TIM PWM输出:产生PWM波(频率固定、占空比可调),实现呼吸灯
  3. TIM PWM输出:可调频率/占空比的PWM波

4.8.2. TIM原理解析

  定时器(Timer)最基本的功能就是定时,可以延伸到测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)等。
  STM32G4 的定时器功能十分强大,共有10个定时器:
  表1 定时器类型
在这里插入图片描述
查看STM32G431RB数据手册(资料包芯片手册中),可获得各个定时器通道的引脚分布,如(资料包芯片手册中)
可以汇总为表2:
在这里插入图片描述
STM32G431的通用 TIMx定时器功能特点包括:
 16 /32 位向上、向下、向上/向下(中心对齐)计数模式,自动装载计数器(TIMx_CNT)。
 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数 为 1~65535 之间的任意数值。
 4 个独立通道(TIMx_CH1~4)
计数器模式
通用定时器可以向上计数、向下计数、向上向下双向计数模式。
 向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
 向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
 中央对齐模式(向上/向下计数):计数器从0开始计数到最大值,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。
在这里插入图片描述
定时时间计算
  基本定时器计数过程主要涉及到三个寄存器内容,分别是计数器寄存器(TIMx_CNT)、预分频器寄存器(TIMx_PSC)、自动重载寄存器(TIMx_ARR),这三个寄存器都是 16 位有效数字,即可设置值为 0 至 65535。
  CNT表示当前计数值,ARR是自动重载的最大计数值。PSC是分频系数,对定时器时钟AB1或AB2进行分频,得到当前计数器的频率。)
  首先设置预分频器寄存器TIMx_PSC (简写成PSC),得到分频后的频率,频率的倒数就是周期时长。如,定时器时钟fCK_PSC =80MKz、(PSC+1)设为(7999+1),这样fCK_CNT /(PSC+1)分频后的频率值就为10kHz,每一个周期时长也就是0.1ms。
  fCK_CNT = fCK_PSC/(PSC+1) // fCK_PSC为定时器时钟频率,来自APB1或者APB2。
  再把把(ARR+1)设为(9999+1)。这样我们得到的定时时长就是1s。
  Tout(定时时间)=(ARR+1)(PSC+1)/ fCK_PSC
PWM波输出
  PWM 输出就是产生一个周期的方波信号,频率、占空比(高电平占总周期的比值)是它的关键参数。
  如下图,假定定时器工作在向上计数PWM模式,且当 CNT(当前计数值)<CCRx(比较寄存器) 时,输出 0,当 CNT>=CCRx 时输出 1。实际上配置CCRx、ARR的数值,就控制PWM波的输出脉宽了。
在这里插入图片描述
  STM32G431 定时器可以用来产生 PWM 输出,其中高级定时器 TIM1 可以输出 4 路。而通用定时器(TIM2、TIM3、TIM4)也可同时产生多达 4 路的 PWM 输出。
在这里插入图片描述
  通常单片机GPIO口只能输出高电平和低电平,可以利用PWM波,通过改变PWM方波的占空比,从而获得不同的模拟电压值。如,100%对应5v,0%对应0v,50%对应2.5v。
在这里插入图片描述
  因此,利用PWM波,可以实现呼吸灯(电压值变化,导致LED亮度强弱变化)、电机调速(电压值变化,导致电机速度变化)等。

4.8.3. TIM定时作用

  定时器(Timer)最基本的功能就是定时,这里以官方例程HAL_10_TIM_BASE为例,阐述TIM定时作用的设计方法,实现流水灯。
定时器的定时设计方法:
 参数配置:PSC、ARR,开启定时中断。可采用STM32CubeMX或者程序设计来实现。
 main.c中调用TIM初始化语句、开启定时中断HAL_TIM_Base_Start_IT(&htim1)。
 编写中断回调函数HAL_TIM_PeriodElapsedCallback,实现功能要求。

1. 初始化配置(STM32CubeMX)

  定时器的参数配置,可以首先使用STM32CubeMX进行初步设置。还可以在程序设计时,进行二次修改。
  以TIM3为例,配置出1HZ的频率,也就是1s发生一次溢出中断。
  80MHZ经过PSC分频,80MHZ/(7999+1) ,得到10KHZ的时钟频率(周期0.0001s)。ARR设为10K-1,则计数10K次,产生溢出中断,即实现1s的计时 。
  STM32CubeMX配置,如下图:
在这里插入图片描述
在这里插入图片描述

2. 应用程序设计(KEIL5)

1)定时器参数配置二次修改、初始化
  如上,STM32CubeMX参数配置完成后,在工程项目中生成对应的初始化函数MX_TIM1_Init(),并在main.c中自动调用。该函数包含了CubeMX所配置的各项参数。
在这里插入图片描述
  PSC、ARR等参数,还可以通过对函数MX_TIM1_Init()内部参数进行二次修改,如,官方例程HAL_10_TIM_BASE中:
在这里插入图片描述
  如上图,其与前述STM32CubeMX中TIM1设置不一样,也就是说MX_TIM1_Init()内部参数可以进行二次修改。PSC=1000,ARR=79,也就是实现近似1/1000s=0.001s计时。
2)开启定时器中断
  定时器初始化配置后,还需要开启定时器中断,使用函数 HAL_TIM_Base_Start_IT (&htim1);其中htim1表示定时器TIM1,定义方法:TIM_HandleTypeDef htim1。通常,通过STM32CubeMX配置TIM1后,在time.c文件中自动定义,直接使用它即可。
在这里插入图片描述
在这里插入图片描述
3)编写中断回调函数
  中断回调函数HAL_TIM_PeriodElapsedCallback()是实现TIM定时的关键。按照其设计框架,需要手动编写其代码,实现不同功能要求。
  从定时器中断原理来说,每个定时器中断,就执行其中断服务函数HAL_TIM_IRQHandler(在库stm32g4xx_hal_tim.c中已定义)。中断服务函数HAL_TIM_IRQHandler,由HAL库提供,无需用户编辑,但其内部自动执行中断回调函数HAL_TIM_PeriodElapsedCallback。
  因此,我们需要编写中断回调函数HAL_TIM_PeriodElapsedCallback,以实现不同功能要求。如官方例程HAL_10_TIM_BASE中,使用TIM1,实现0.1s流水灯效果。中断回调函数HAL_TIM_PeriodElapsedCallback代码编辑为:

/* USER CODE BEGIN 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	static uint16_t counter = 0;
	static uint16_t led = 0x0001, i = 0, dir = 0;
	
	if(++counter == 100){
		counter = 0;
		GPIOC->ODR = ~(led << (8 + i));
		GPIOD->BSRR |= GPIO_PIN_2;
		__nop();__nop();__nop();
		GPIOD->BRR |= GPIO_PIN_2;
		
		if(dir == 0){
			if(++i == 7){
				dir = 1;
			}
		}else{
			if(--i == 0){
				dir = 0;
			}
		}
	}
	//HAL_TIM_Base_Start_IT(&htim1);
}
/* USER CODE END 0 */

  前面参数配置中,实现了定时器0.001s计时,也就是说0.001s发生一次中断,每0.001s执行一次中断回调函数HAL_TIM_PeriodElapsedCallback。因此,中断回调函数内部每100次执行一次LED显示、移位操作,从而实现0.001s *100=0.1s流水灯。

4.8.4. PWM输出

这里,要求实现(固定频率,占空比可调:呼吸灯):初始化定时器定时10ms,输出PWM,使LED1闪烁。

1. 初始化配置(STM32CubeMX)

STM32CubeMX中,对定时器PWM方式配置分成2个方面:
1)PWM输出引脚的设定
LED1对应的GPIO是PC8,查阅STM32G431RB数据手册,PC8可用的定时器可用TIM3的通道3。若选用其他GPIO输出PWM,同理,还得查阅该手册,找到合适的TIM通道:
在这里插入图片描述
  STM32CubeMX中设置PC8输出方式为TIM3_CH3。PD2设置为Output。
其他GPIO、SYS、时钟树(80MHz)配置参考前述。(图略)
2)TIM3的PWM方式配置
  如下图,STM32CubeMX中对TIM3的PWM设置。
其中,TIM3的定时周期配置成10ms(PSC=7999,ARR=99),才能达到呼吸灯显示效果,否则呼吸灯显示不明显。
在这里插入图片描述
在这里插入图片描述
其中,PWM mode1和mode2的概念:
在这里插入图片描述
  模式1和模式2区别不大,选用模式1即可。
  上图中,占空比默认为0,后面在程序设计中可修改。
3)main.c程序设计
  与PWM相关的函数有4个:
 回调函数: void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
 开启PWM: HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
 停止PWM :HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
 配置占空比:__HAL_TIM_SetCompare (&htim3,TIM_CHANNEL_3, i);//i取值0~ARR
 设置自动重装值: __HAL_TIM_SET_AUTORELOAD(htim, arr)
  这里,主要使用开启PWM、配置占空比2个函数,实现呼吸灯效果。main函数的程序设计如下:

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);//关闭锁存器
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);//使能定时器3的通道3,产生PWM
  /* USER CODE END 2 */
   /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);//开启锁存器
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_All, 1);//先全部关闭LED
		
	uint16_t i=0;
	for(i=0;i<100;i++){__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_3,i);HAL_Delay(20);}
	for(i=100;i>0;i--) {__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_3,i); HAL_Delay(20);}
		
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);//关闭锁存器
  }
}

  其中,HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3)开启PWM输出,就是在引脚上输出所设定的PWM波。
  __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_3,i),通过i的变化,使PWM波占空比变化,,LED显示出呼吸灯效果。
  编译、下载该程序,可实现固定频率,占空比可调的PWM波输出,显示呼吸灯效果。

2. 可修改频率、占空比的PWM波

  部分题目要求实现频率和占空比都可调节的PWM波,那么,在STM32CubeMX配置中略作修改。
  如下图,在STM32CubeMX中,对TIM设置成可修改频率和占空比:
在这里插入图片描述
  则,程序设计可使用以下2个宏定义函数,进行参数修改:

  • 设置自动重装值: __HAL_TIM_SET_AUTORELOAD (&htim3, arr)
    通过设置自动重装值,可获得PWM信号周期为Tpwm=(arr+1)(PSC+1)/ 80MHz,其中PSC由CubeMX配置(也可以TIM初始化程序中二次修改)。
  • 配置占空比:__HAL_TIM_SetCompare (htim, Channel, cmp);// cmp取值范围0~arr
    占空比=cmp/(arr+1)。

如,在main.c中编辑函数TIM_Proc():

void TIM_Proc(void)
{
    __HAL_TIM_SET_AUTORELOAD (&htim3, 9999);
    __HAL_TIM_SetCompare (&htim3, TIM_CHANNEL_3, 2000);
}

  最后在while中调用TIM_Proc(),就可以实现TIM3_CH1输出的PWM波,频率为100Hz(PSC=79,ARR=9999),占空比为20%(2000/(ARR+1))。
  一般题目中测量PWM波要求使用PA6或PA7引脚。查询TIM引脚分布,可选择PA6–》TIM3_CH1,PA7–》TIM3_CH2。STM32CubeMX配置和程序设计方法,参看前述。
在这里插入图片描述
使用示波器,就可以从PA6、PA7观测PWM波,或者打开KEIL仿真功能,检测PA6、PA7的输出波形。

3. 小练习

第十二届蓝桥杯嵌入式省赛对PWM的考察为例,PWM部分要求:
在这里插入图片描述
设计思路:
1) STM32CubeMX中配置PA7–》TIM3_CH2输出PWM波:2KHz(PSC=399,ARR=99)
2)利用函数__HAL_TIM_SetCompare (&htim3,TIM_CHANNEL_2,20),实现20%占空比。
注意开启PWM:HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1)
3) 按键切换控制,参看4.3节按键控制程序设计(按键扫描函数Key_scan,按键服务函数Key_proc)

4.8.5. 小结

STM32CubeMX配置:输出引脚,TIMx_CHx,PSC,ARR
TIM定时和PWM输出,对应的函数有所不同。

  • TIM定时(中断方式)的库函数:
     开启定时中断:HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
     关闭定时中断:HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim);
     中断回调函数:HAL_TIM_PeriodElapsedCallback(htim);
  • PWM的库函数/宏定义(_HAL):
     回调函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
     开启PWM HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
     停止PWM HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
     配置占空比: __HAL_TIM_SetCompare (htim, Channel, cmp);
     设置自动重装值ARR: __HAL_TIM_SET_AUTORELOAD (&htim3, arr);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《STM32单片机开发应用教程(HAL库版)—基于国信长天嵌入式竞赛实训平台(CT117E-M4)》第四章4.8 TIM---PWM输出实验 的相关文章

  • 硬件面试题目

    1 请列举您知道的电阻 电容 电感品牌 最好包括国内 国外品牌 电阻 日本 muRata 村田 Panasonic 松下 ROHM 罗姆 susumu TDK 中国 YAGEO 国巨 FH 风华 电容 日本 Matsushita 松下 mu

随机推荐

  • Windows Git配置SSH

    进入桌面 或者文件管理中右键 gt 打开Git命令窗口 生成ssh keygen 命令 wolfs com 为你的Git账号 ssh keygen t rsa C wolfs com 必要信息有所打码 可自行更改 然后提示你输入密码进行验证
  • vue总引入VConsole

    第一种 使用import的方式 通过main js中引入 先创建一个全局的vconsole js import Vconsole from vconsole const vConsole new Vconsole export defaul
  • mybatis缓存级别以及如何开启二级缓存

    一级缓存 范围 一级缓存是基于 SqlSession 的本地缓存 与单个 SqlSession 相关联 生命周期 一级缓存的生命周期是短暂的 仅在同一个 SqlSession 内有效 当在同一个 SqlSession 中执行相同的查询时 第
  • fcn从头开始_如何使用Go从头开始构建区块链

    fcn从头开始 介绍 Introduction With Web 3 0 and blockchain becoming more mainstream every day do you know what blockchain is Do
  • 复杂网络博弈:用matlab实现囚徒困境

    复现方格网下囚徒困境博弈程序 分别画出b 0 8 2之间 以0 2为间隔的 均衡状态下的网络快照 及合作者比例变化图 设置囚徒困境博弈参数 b values 0 8 0 2 2 0 合作者得到的收益相对于双方都不合作时的收益的比例 N 20
  • 单个el-form-item中有多个必填

    element ui组件里的el form设置为必填都是一对一的 而一个里面包含多个选择框或输入框的却无法实现 怕自己说不清楚 附一张图吧 图中 下发周期 是一个el form item的label名 下面的都包含在里面 设置必填使二者都生
  • 如何在知乎上进行markdown创作?

    前言 废话 题主和大家一样 也是苦苦找不到解决办法 中到有一天 偶然看到一款神器 方才完成由猴到人的蜕变 话不多说 直接上教程 404警告 本猿写教程一向很结构化 看不懂就留言吧 1 正文 如何在知乎上进行markdown创作 所需工具 已
  • LVS+Web

    一 LVS NAT模式 1 根据拓扑图搭建好实验环境 拓扑如下 2 rhel1配置 1 编译ipvsadm源码包 2 ipvsadm配置与启动 3 查看ipvsadm配置 4 开启内核路由转发 vim etc sysctl conf 修改如
  • 阿里云轻量应用服务器使用指南

    阿里云轻量应用服务器使用指南 云服务器 云服务器 Elastic Compute Service ECS 是一种简单高效 安全可靠 处理能力可弹性伸缩的计算服务 其管理方式比物理服务器更简单高效 用户无需提前购买硬件 即可迅速创建或释放任意
  • mybatis—PageHelper分页失效问题

    当PageHelper分页失效时 可以看一下PageHelper开启startPage后是否查询了多个list 是否在通过多个mapper xml方法返回了多个list PageHelper startPage page rows eg 错
  • 【问题记录】如何使用 pip 在 linux 上安装 pytorch

    一 进入 pytorch 官网 pytorch 官网 https pytorch org 二 在页面选择环境 三 复制官网弹出的命令并运行即可 pip3 install torch torchvision torchaudio index
  • loadrunner负载发生器和性能计数器

    一 添加负载发生器 如果发现不能同时设置本机和负载机 解决办法是先选择Scenario gt Convert Scenario to the Percentage Mode 将场景模式由用户组切换为百分比 然后在已经添加好的Load Gen
  • rabbitmq java 删除交换机与队列

    rabbitmq java 删除交换机与队列 删除指定队列 直接删除 channel queueDelete queueName 删除指定交换机 直接删除 channel exchangeDelete exchangeName 清空指定队列
  • 工作日记——@RequestMapping 的String&&View适配 ————2016-1-14

    问题描述 工作上遇到要在一个RequestMapping 方法里适配返回值为string 或者json对象 以下是解决方案 部分涉及业务逻辑请忽略 1 RequestMapping方法 RequestMapping method Reque
  • 前端Base64编码知识,一文打尽

    原文 https juejin cn post 6989391487200919566 作者 云的世界 掘金专栏 前端基础进阶 大厂技术 高级前端 Node进阶 点击上方 程序员成长指北 关注公众号 回复1 加入高级Node交流群 前言 本
  • 使用Python抓取同花顺资金流数据

    今天我们通过一个例子来介绍python爬取数据的一般步骤 用到的工具包括python的经典模块requests和BeautifulSoup 另外结合刚学习的任务流工具TaskFlow来完成代码开发 我们先来看一下要爬取的数据 网址是http
  • IDEA导出可执行的jar,包含class以及资源文件一起打包

    1 点击File gt Project Structure gt Artifacts 2 点 选择Directory Content 选择资源文件所在文件夹即可 3 最后build Artifacts
  • linux彻底卸载nodejs,Linux 卸载删除node和npm并重新安装(升级)

    卸载 1 先卸载npm sudo npm uninstall npm g 2 卸载node yum remove nodejs npm y 看看是否有残留 进入 usr local lib 删除所有 node 和 node modules文
  • 华为OD机试真题 Java 实现【代表团坐车】【2023 B卷 200分】,附详细解题思路

    目录 专栏导读 一 题目描述 二 输入描述 三 输出描述 四 解题思路 五 Java算法源码 六 效果展示 1 输入 2 输出 3 说明 华为OD机试 2023B卷题库疯狂收录中 刷题点这里 专栏导读 本专栏收录于 华为OD机试 JAVA
  • 《STM32单片机开发应用教程(HAL库版)—基于国信长天嵌入式竞赛实训平台(CT117E-M4)》第四章4.8 TIM---PWM输出实验

    写在前面 STM32单片机开发应用教程 HAL库版 基于国信长天嵌入式竞赛实训平台 CT117E M4 第四章4 8 TIM PWM输出实验 讲解TIM 定时与PWM输出的STM32CubeMX配置和程序设计方法 官方例程下载 https