《STM32单片机开发应用教程(HAL库版)—基于国信长天嵌入式竞赛实训平台(CT117E-M4)》第四章4.9 TIM---输入捕获(脉冲频率测量)实验
写在前面——
《STM32单片机开发应用教程(HAL库版)—基于国信长天嵌入式竞赛实训平台(CT117E-M4)》第四章4.9 TIM—输入捕获(脉冲频率测量)实验,讲解TIM输入捕获的原理,以及STM32CubeMX配置和程序设计方法
官方例程下载:https://pan.baidu.com/s/1QC5BnDgY1m1me6-ihQ_OUQ?pwd=nqb1
提取码:nqb1
目录
- 4.9 TIM---输入捕获(脉冲频率测量)实验
- 4.9.1. 实验任务
- 4.9.2. TIM输入捕获的原理解析
- 4.9.3. 初始化配置(STM32CubeMX)
- 4.9.4. 应用程序设计(KEIL5)
- 1. TIM输入捕获HAL库函数
- 2. TIM输入捕获与测频、LCD显示
- 3. TIM捕获频率和脉宽(占空比)
- 4.9.5. 小结
4.9 TIM—输入捕获(脉冲频率测量)实验
4.9.1. 实验任务
- TIM普通输入捕获模式:参看官方例程HAL_11_TIM_FRQ,实现板载信号的输入捕获,测量其频率。
- TIM输入捕获PWM模式:测量脉宽/占空比。
4.9.2. TIM输入捕获的原理解析
输入捕获可以对输入信号的上升沿,下降沿或者双边沿进行捕获,可以测量输入信号的脉宽和测量 PWM 输入信号的频率和占空比。
输入捕获分为普通输入捕获模式(测频)和PWM输入模式(测频+占空比)。
输入通道与捕获通道的区别
输入通道:需要被测量的信号从定时器的外部引脚 TIMx_CH1/2/3/4 进入,通常叫 TI1/2/3/4,在后面的捕获讲解中对于要被测量的信号我们都以 TIx 为标准的叫法
捕获通道:捕获通道就是输入捕获整体结构图中的 IC1/2/3/4,每个捕获通道都有相对应的捕获寄存器 CCR1/2/3/4,当发生捕获的时候,计数器 CNT 的值就会被锁存到捕获寄存器。
输入通道是用来输入信号的,捕获通道是用来捕获输入信号的通道,一个输入通道的信号可以同时输入给两个捕获通道。
普通输入捕获模式
当捕获到信号的跳变沿的时候,把计数器 CNT 的值锁存到捕获寄存器 CCR 中,这就是普通输入捕获模式。
普通输入捕获模式,通常用于测量频率。其原理简单来说,以上升沿捕获为例,如上图:
第一次上升沿来临时,发生捕获中断,记录value1=当前计数值CNT。
当第二次上升沿来临,再次发生捕获中断,记录value3=当前计数值CNT,并清除捕获记录标记。
根据value3和value1差值,计算出输入信号的频率。
PWM输入模式
普通输入捕获模式也可以用来计算脉宽(占空比),但是配置复杂。一般使用PWM输入模式,同时计算频率和脉宽。
PWM 输入模式需要占用两个捕获通道IC1和IC2。
当使用 PWM 输入模式的时候,因为一个输入通道(TIx)会占用两个捕获通道(ICx),所以一个定时器在使用 PWM 输入的时候最多只能使用两个输入通道(TIx),如下图。
如上图,PWM 信号由输入通道 TI1 进入,信号会被分为两路,一路是 TI1FP1,另外一路是 TI2FP2。其中一路是测周期,另一路是测占空比。由此,定时器的输入捕获有两个功能,直接捕获模式和间接捕获模式;
直接捕获:只能捕获本身通道的脉冲信号;
间接模式:可以捕获此定时器每个通道的脉冲信号。
通常,测频支路设置成直接捕获模式,而测脉宽的支路设置成间接模式。
PWM 输入模式原理:
当第一次上升沿时,IC1和IC2同时捕获中断,计数器CNT清零;
到了下降沿的时候,IC2捕获中断,此时计数器CNT的值被锁存到捕获寄存器CCR2中;
到了下一个上升沿的时候,IC1捕获中断,计数器CNT的值被锁存到捕获寄存器CCR1中
CCR2测量的是脉宽,CCR1测量的是周期。
可见,输入捕获的两大核心功能:
1)捕获定时器的数值。
2)产生中断,类似于外中断,比如,上升沿产生中断。
开发板上配置了两个555作为信号发生器(U8,U7),通过可调电阻R40,R39调节信号频率,两个输出引脚分别连接在PA15和PB4引脚上,如下图。
查阅芯片资料,可以得知这两个引脚可用作以下定时器的输入捕获:PA15–> TIM2_CH1(AF1); PB4 --> TIM3_CH1(AF2)。
4.9.3. 初始化配置(STM32CubeMX)
以PA15输入信号进行TIM2_CH1输入捕获、测频为例,在STM32CubeMX中进行配置。
对PA15引脚,选择TIM2_CH1。
这里选择复位Reset模式、Tl1FP1(由定时器的输入信号触发)、内部时钟。
定时频率设置为1MHz;上升沿触发;直接捕获方式。
NVIC中,打开TIM2中断,可设置中断服务优先级,
SYS、时钟树(80MHz)、项目名称、路径等配置,参看前述章节。
LCD无需在STM32CubeMX中配置,参看前述方法,复制相关文件到本项目工程中。
4.9.4. 应用程序设计(KEIL5)
1. TIM输入捕获HAL库函数
TIM相关的HAL库函数在stm32g4xx_hal_tim.h文件中可查询到。这里,仅使用TIM作输入捕获(中断方式),主要使用的库函数有:
- //中断方式启动捕获–启动输入捕获功能,并使能相应的中断
HAL_StatusTypeDef HAL_TIM_IC_Start_IT (TIM_HandleTypeDef *htim, uint32_t Channel) - //中断方式停止捕获–关闭定时器某一通道的输入捕获功能和相应中断
HAL_StatusTypeDef HAL_TIM_IC_Stop_IT (TIM_HandleTypeDef *htim, uint32_t Channel) - //获取当前的捕获值–读取CCRx寄存器的值
uint32_t HAL_TIM_ReadCapturedValue (TIM_HandleTypeDef *htim, uint32_t Channel)
还可以使用已定义宏(也在stm32g4xx_hal_tim.h):
读取计数值:__HAL_TIM_GET_COUNTER (&htim)
重新设置计数值:__HAL_TIM_SET_COUNTER (&htim, COUNTER)
建议使用函数HAL_TIM_ReadCapturedValue捕获计数值。
- //输入捕获中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
2. TIM输入捕获与测频、LCD显示
根据前面4.9.3节,完成TIM输入捕获的STM32CubeMX配置。KEIL5打开工程项目后,首先把LCD初始化相关的操作完成,参看4.4 LCD显示实验,添加lcd.c、lcd.h、font.h到本项目中,并在main.c中完成初始化。
1)编写输入捕获的中断回调函数
输入捕获发生中断时,自动执行其中断回调函数HAL_TIM_IC_CaptureCallback,但是中断回调函数需要在main.c中手动编写,如:
/* USER CODE BEGIN 0 */
uint32_t Freq;//获得频率值,全局变量
uint16_t Counter;//获得计数值,全局变量
/* 输入捕获中断服务函数 上升沿中断 */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM2) //TIM2判断{if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) //CH1判断{Counter=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1)+1;//获取计数值+1Freq=1000000/Counter;//计算频率}}
}
/* USER CODE END 0 */
2)编写LCD显示服务函数
简单的LCD显示任务,可以直接在main主函数中编写,如官方例程HAL_10_TIM_BASE所示,在用户代码区域编写:
/* USER CODE BEGIN 2 */
char buf[20];LCD_Init();LCD_Clear(Blue);LCD_SetBackColor(Blue);LCD_SetTextColor(White);LCD_DisplayStringLine(Line0, (uint8_t *)" ");LCD_DisplayStringLine(Line1, (uint8_t *)" ");LCD_DisplayStringLine(Line2, (uint8_t *)" TIM Test ");LCD_DisplayStringLine(Line3, (uint8_t *)" ");LCD_DisplayStringLine(Line4, (uint8_t *)" ");LCD_SetBackColor(White);LCD_SetTextColor(Blue);LCD_DisplayStringLine(Line5, (uint8_t *)" ");LCD_DisplayStringLine(Line6, (uint8_t *)" TIM2 CH1 ");LCD_DisplayStringLine(Line7, (uint8_t *)" ");LCD_DisplayStringLine(Line8, (uint8_t *)" ");LCD_DisplayStringLine(Line9, (uint8_t *)" ");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);//开启输入捕获中断while (1){/* USER CODE END WHILE */sprintf(buf, " FRQ(R40):%dHz ", Freq);LCD_DisplayStringLine(Line8, (uint8_t *)buf);HAL_Delay(200);/* USER CODE BEGIN 3 */}/* USER CODE END 3 */
其中,变量Freq是由中断回调函数HAL_TIM_IC_CaptureCallback所计算的频率值。
注意,添加#include “stdio.h”,可避免sprintf的警告错误。
这里,编写一个LCD显示服务函数,以完成LCD显示任务,如:
/* LCD显示服务函数 */
void LCD_proc()
{uint8_t buf[21];
sprintf((char*)buf, " Freq(R40):%dHz ",Freq);
LCD_DisplayStringLine(Line8, buf); HAL_Delay(200);
}
/* USER CODE END 2 */
再在while (1) 中调用LCD_proc(),如下(包含LCD初始化):
/* USER CODE BEGIN 2 */LCD_Init();LCD_Clear(Blue);LCD_SetBackColor(Blue);LCD_SetTextColor(White);LCD_DisplayStringLine(Line0, (uint8_t *)" ");LCD_DisplayStringLine(Line1, (uint8_t *)" ");LCD_DisplayStringLine(Line2, (uint8_t *)" TIM Test ");LCD_DisplayStringLine(Line3, (uint8_t *)" ");LCD_DisplayStringLine(Line4, (uint8_t *)" ");LCD_SetBackColor(White);LCD_SetTextColor(Blue);LCD_DisplayStringLine(Line5, (uint8_t *)" ");LCD_DisplayStringLine(Line6, (uint8_t *)" TIM2 CH1 ");LCD_DisplayStringLine(Line7, (uint8_t *)" ");LCD_DisplayStringLine(Line8, (uint8_t *)" ");LCD_DisplayStringLine(Line9, (uint8_t *)" ");HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);//开启输入捕获中断 /* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){LCD_proc();/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
编译、下载后,LCD可显示当前输入信号的频率值,旋转R40电阻,频率值将随着变化:
3. TIM捕获频率和脉宽(占空比)
前面实现了对输入信号的测频功能,若要测量出其占空比,则需要另一个通道同时进行脉宽计数,以计算占空比。此种方式,也就是输入捕获的PWM输入模式。
1)STM32CubeMX配置PWM模式
参看前述输入捕获PWM模式原理,测频通道(CH1)配置成直接模式、上升沿触发,测量脉宽通道(CH2)配置成间接模式、下降沿触发。
其他配置,参看4.9.3节(PA15— TIM2_CH1,NVIC中断,SYS)等。
2)测频+占空比程序设计
LCD配置,同前述。
与输入捕获的测频程序设计类同,设计测频+占空比的输入捕获中断回调函数HAL_TIM_IC_CaptureCallback,LCD显示服务函数LCD_proc(),并在main.c中做好TIM、LCD初始化。
中断回调函数HAL_TIM_IC_CaptureCallback代码为:
uint32_t Freq,Duty;//获得频率值,占空比
uint16_t T_Count,D_Count;//获得计数值
//输入捕获中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM2){if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){T_Count = HAL_TIM_ReadCapturedValue (htim,TIM_CHANNEL_1)+1;Freq = 1000000 / T_Count;Duty = (float)D_Count/T_Count * 100;}else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2){D_Count = HAL_TIM_ReadCapturedValue (htim,TIM_CHANNEL_2)+1;} }
}
其中,通过Duty = (float)D_Count/T_Count * 100;计算出占空比。
LCD显示服务函数LCD_proc代码为:
/* LCD显示服务函数 */
void LCD_proc()
{uint8_t buf[21];sprintf((char*)buf, " Freq(R40):%dHz ",Freq);LCD_DisplayStringLine(Line8, buf); sprintf((char*)buf, " Duty(R40):%4.2f%% ",(double)Duty);LCD_DisplayStringLine(Line9, buf); HAL_Delay(200);
}
其中,%4.2f%%设置显示格式:带2位小数点的4位浮点数,百分号用%%。
main函数其他部分,与前面测频程序类同,注意,需要开启CH1和CH2通道中断:
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);//开启CH1输入捕获中断
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);//开启CH2输入捕获中断
4.9.5. 小结
- STM32CubeMX中,普通捕获输入模式和PWM模式,配置有所区别。
普通捕获输入模式是单通道,直接模式。
PWM模式是双通道,CH1直接模式,CH2间接模式。 - TIM作输入捕获(中断方式),主要使用的库函数有:
//中断方式启动捕获
HAL_StatusTypeDef HAL_TIM_IC_Start_IT (TIM_HandleTypeDef *htim, uint32_t Channel)
//中断方式停止捕获
HAL_StatusTypeDef HAL_TIM_IC_Stop_IT (TIM_HandleTypeDef *htim, uint32_t Channel)
//获取当前的捕获值
uint32_t HAL_TIM_ReadCapturedValue (TIM_HandleTypeDef *htim, uint32_t Channel)
输入捕获中断服务函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) - 频率、占空比等参数计算,在中断服务函数HAL_TIM_PeriodElapsedCallback中程序设计。
《STM32单片机开发应用教程(HAL库版)—基于国信长天嵌入式竞赛实训平台(CT117E-M4)》第四章4.9 TIM---输入捕获(脉冲频率测量)实验相关推荐
- 《STM32单片机开发应用教程(HAL库版)---基于国信长天嵌入式竞赛实训平台(CT117E-M4)》第二章 软件安装与使用
写在前面-- 作为<STM32单片机开发应用教程(HAL库版)-基于国信长天嵌入式竞赛实训平台(CT117E-M4)>系列之第二章,本章节将介绍开发软件STM32CubeMX和KEIL5的 ...
- 《STM32单片机开发应用教程(HAL库版)—基于国信长天嵌入式竞赛实训平台(CT117E-M4)》第四章4.3 按键控制实验
写在前面-- <STM32单片机开发应用教程(HAL库版)-基于国信长天嵌入式竞赛实训平台(CT117E-M4)>第四章4.3 按键控制实验,讲述按键控制的编程方法 官方例程下载:http ...
- 《STM32单片机开发应用教程(HAL库版)—基于国信长天嵌入式竞赛实训平台(CT117E-M4)》第四章4.1 LED显示控制实验
写在前面-- <STM32单片机开发应用教程(HAL库版)-基于国信长天嵌入式竞赛实训平台(CT117E-M4)>第四章4.1,本节将通过LED显示控制实验,学习STM32G431的开发技 ...
- STM32单片机开发应用教程 (HAL库版) ---基于国信长天嵌入式竞赛实训平台(CT117E-M4)教程汇总 与第一章 硬件平台简介
写在前面-- 作为<STM32单片机开发应用教程(HAL库版)-基于国信长天嵌入式竞赛实训平台(CT117E-M4)>教程汇总,第一章将介绍国信长天嵌入式竞赛实训平台(CT117E-M4) ...
- HAL库版STM32双轮自平衡车(四) ———— 原理图以及PCB绘制
系列文章目录 HAL库版STM32双轮自平衡车(一) ---代码思路和PID基础精讲 HAL库版STM32双轮自平衡车(二) --- CubeMX的配置.原理图接线.物料准备 HAL库版STM32双轮 ...
- HAL库版STM32双轮自平衡车(三) ———代码精讲
系列文章目录 编码电机测速 HAL库OLED的使用 HAL库版STM32双轮自平衡车(一) ---代码思路和PID基础精讲 HAL库版STM32双轮自平衡车(二) --- CubeMX的配置.原理图接 ...
- HAL库版STM32双轮自平衡车(一) ———代码思路和PID基础精讲
系列文章目录 HAL库版STM32双轮自平衡车(一) ---代码思路和PID的简单介绍(本篇) HAL库版STM32双轮自平衡车(二) --- CubeMX的配置.原理图接线.物料准备 HAL库版ST ...
- HAL库版STM32双轮自平衡车(五) ———— 调参
系列文章目录 HAL库版STM32双轮自平衡车(一) ---代码思路和PID基础精讲 HAL库版STM32双轮自平衡车(二) --- CubeMX的配置.原理图接线.物料准备 HAL库版STM32双轮 ...
- HAL库版STM32双轮自平衡车(二) ——— CubeMX的配置、原理图接线、物料准备
系列文章目录 编码电机测速 HAL库版 0.96'OLED的使用 HAL库版STM32双轮自平衡车(一) ---代码思路和PID的简单介绍 HAL库版STM32双轮自平衡车(二) --- CubeMX ...
最新文章
- 看看是否有人用USB偷插你的电脑
- Linux 小知识翻译 - 「RAID」
- 小程序分享到朋友圈功能_来啦!小程序支持分享朋友圈
- 要闻君说:IBM最新量子计算机真真像个艺术品!鹅厂正式成立了自己的技术委员会哇!联想竟然也试着做了一款智能闹钟?...
- 终于来了!iOS 13大更新发布,新功能均与新冠疫情有关
- Python+OpenCV:理解K-Means聚类(K-Means Clustering)
- CodeForces - 245H Palindromes区间dp_记忆化搜索
- 五种食物可以吃掉黑眼圈
- WPS启动不再默认展示“稻壳”页面 - 去除稻壳的方法
- 局域网中的几大分类,包含以太网,FDDI网,令牌环网,ATM网
- 利用pdfbox和itext包将pdf转换为图片
- 不能登录Google账号
- 简明理解 行列式和秩
- 2048游戏英雄榜java_2048技巧 2048游戏排行榜挑战方法攻略详解
- 数据库设计之备用字段
- 【历史上的今天】3 月 17 日:苹果起诉微软;CN 域名开放注册;赛博朋克之父出生
- awd——waf部署
- 计算机考研英语一和英语二的区别,考研英语一和英语二的区别,考研党知道了吗?...
- 在华清远见培训的感受(实习总结)
- 小白也能重装系统?写给小白的一封信--重装纯净版Win10系统
热门文章
- 求1的阶乘+2的阶乘+3的阶乘+4的阶乘+…+n的阶乘
- 《变形金刚》真人电影知识普及贴-转帖
- 周鸿袆: 教您打造十页完美商业计划书
- 入侵你Linux服务器的一万种玩法...
- 阿里云服务器被攻击的危害有多大
- Oracle中编码与字符转换
- 嵌入式课程---嵌入式Linux的直流电机驱动开发
- es6方法 数组去重 多个数组去重 数组对象去重
- iOS 自动布局 Autolayout 报错:Unable to simultaneously satisfy constraints.
- OSPF---路由备份的设计实验