你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】HAL库 STM32CubeMX教程八---定时器输入捕获

[复制链接]
STMCU小助手 发布时间:2022-3-25 10:29
前言:
本系列教程将外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用


所用工具:

1、芯片: STM32F407ZET6/STM32F103ZET6

2、STM32CubeMx软件

3、IDE: MDK-Keil软件

4、STM32F1xx/STM32F4xxHAL库

知识概括:

通过本篇博客您将学到:

SMT32定时器输入捕获

测量PWM频率和占空比


输入捕获
输入捕获概念
输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32的定时器,除了TIM6、TIM7,其他的定时器都有输入捕获的功能。

输入捕获的工作原理

20190813094532466.png
①先设置输入捕获为上升沿检测,

②记录发生上升沿时TIMx_CNT(计数器)的值

③配置捕获信号为下降沿捕获,当下降沿到来的时候发生捕获

④记录此时的TIMx_CN(计数器)T的值

⑤前后两次TIMx_CNT(计数器)的值之差就是高电平的脉宽。同时根据TIM的计数频率,我们就能知道高电平脉宽的准确时间。


简单说:

当你设置的捕获开始的时候,cpu会将计数寄存器的值复制到捕获比较寄存器中并开始计数,当再次捕捉到电平变化时,这是计数寄存器中的值减去刚才复制的值就是这段电平的持续时间,你可以设置上升沿捕获、下降沿捕获、或者上升沿下降沿都捕获,


输入捕获的工作流程(对应CubeMx的四个选项)

20180419215648175.png

设置输入捕获滤波器

STM32在很多功能中都提供了滤波器,滤波器的功能简单来说就是多次检测视为一次有效,达到滤波效果,

数字滤波器由一个事件计数器组成,假设我们是检测高电平,滤波N次,那么记录到N个事件后计数器会产生一个输出的跳变。也就是说连续N次采样检测,如果都是高电平,则说明这是一个有效的电平信号,这样便可以过滤掉那些因为某些而干扰产生的一些信号        

输入捕获滤波器IC1F[3:0],这个用于设置采样频率和数字滤波器长度。其中:fCK_INT是定时器的输入频率,fDTS是根据TIMx_CR1的CKD[1:0]的设置来确定的。

设置输入捕获极性

设置具体为那种
捕获事件

可以设置上升沿捕获、下降沿捕获、或者上升沿下降沿都捕获

设置输入捕获映射关系
STM32为了更好的优化使用,TIMx_CH1通道1捕捉到的信号可以传输到IC1,TIMx_CH1捕捉到的信号也可以连接到IC2,TIMx_CH2捕捉到的信号也可以连接到IC2,也可以连接到IC2

20190813111456218.png


设置输入捕获分频器
设置每N个事件触发一次捕获,可以设置为1/2/4/8次检测到电平变化才触发捕获

溢出时间计算:
aHR0cHM6Ly9pbWFnZXMyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTIwNzU3Ni8yMDE4MDUvMTIwNzU3Ni0y.png

t1时刻检测到高电平,发生中断,在中断里将计数值置0,开始记溢出次数N,

其中每计数0xFFFF次溢出一次,直到t2时刻跳变回低电平,

获取最后一次溢出时到t2时刻的计数值TIM5CH1_CAPTURE_VAL

则  高电平时间 = 溢出次数*65535+TIM5CH1_CAPTURE_VAL     us ;根据定时器初始化时的频率即可计算出溢出总次数所占用的时间,即为高电平时间。

如果计数器值为 32 bit   那么最大为0xFFFFFFFF      

高电平时间:

20190813172958716.png


输入捕获的工作框图

20180419213733338.png


工程创建
设置RCC


设置高速外部时钟HSE 选择外部时钟源

20190810145615696.png

2设置时钟

2019081117400555.png

我的是  外部晶振为8MHz
1选择外部时钟HSE 8MHz   
2PLL锁相环倍频72倍
3系统时钟来源选择为PLL
4设置APB1分频器为 /2
5 这时候定时器的时钟频率为72Mhz

3定时器配置

20190813120324793.png

这里我们选择TIM5的通道1

预分频系数为71   计数时钟频率就是 72MHz/(71+1) = 1MHz        此时1us计数一次
自动加载值设置为32bit最大值  0xFFFFFFFF         
上升沿捕获
不分频
滤波值为8

同时在NVIC一栏使能TIM5的中断

对应引脚设置下拉电阻,保证没有信号输入的时候电平稳定

20190813152340197.png

4项目文件设置

20190811193124463.png

1 设置项目名称
2 设置存储路径
3 选择所用IDE

2019080921100765.png

5创建工程文件

然后点击GENERATE CODE  创建工程

配置下载工具
新建的工程所有配置都是默认的  我们需要自行选择下载模式,勾选上下载后复位运行

20190809172359875.png

例程实现:
定义变量:
  1. /* USER CODE BEGIN 0 */
  2.     uint32_t capture_Buf[3] = {0};   //存放计数值
  3.     uint8_t capture_Cnt = 0;    //状态标志位
  4.     uint32_t high_time;   //高电平时间
  5. /* USER CODE END 0 */
复制代码

在 while(1)中的用户代码区 3,写入TIM2 CH1通道的输入捕获控制和数据处理

  1. while (1)
  2. {
  3.     /* USER CODE END WHILE */

  4.     /* USER CODE BEGIN 3 */
  5.   switch (capture_Cnt){
  6.         case 0:
  7.                 capture_Cnt++;
  8.                 __HAL_TIM_SET_CAPTUREPOLARITY(&htim5, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
  9.                 HAL_TIM_IC_Start_IT(&htim5, TIM_CHANNEL_1);        //启动输入捕获       或者: __HAL_TIM_ENABLE(&htim5);
  10.                 break;
  11.         case 3:
  12.                 high_time = capture_Buf[1]- capture_Buf[0];    //高电平时间
  13.                 HAL_UART_Transmit(&huart1, (uint8_t *)high_time, 1, 0xffff);   //发送高电平时间
  14.                                 
  15.                                 
  16.                 HAL_Delay(1000);   //延时1S
  17.                 capture_Cnt = 0;  //清空标志位
  18.                 break;
  19.                                 
  20.         }
  21. }
  22. /* USER CODE END 3 */
复制代码

在main函数下方添加中断回调函数:

  1. /* USER CODE BEGIN 4 */
  2. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
  3. {
  4.         
  5.         if(TIM5 == htim->Instance)
  6.         {
  7.                 switch(capture_Cnt){
  8.                         case 1:
  9.                                 capture_Buf[0] = HAL_TIM_ReadCapturedValue(&htim5,TIM_CHANNEL_1);//获取当前的捕获值.
  10.                                 __HAL_TIM_SET_CAPTUREPOLARITY(&htim5,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);  //设置为下降沿捕获
  11.                                 capture_Cnt++;
  12.                                 break;
  13.                         case 2:
  14.                                 capture_Buf[1] = HAL_TIM_ReadCapturedValue(&htim5,TIM_CHANNEL_1);//获取当前的捕获值.
  15.                                 HAL_TIM_IC_Stop_IT(&htim5,TIM_CHANNEL_1); //停止捕获   或者: __HAL_TIM_DISABLE(&htim5);
  16.                                 capture_Cnt++;   
  17.                 }
  18.         
  19.         }
  20.         
  21. }
  22. /* USER CODE END 4 */
复制代码

具体流程:

1.设置TIM5 CH1为输入捕获功能;  

2.设置上升沿捕获;

3.使能TIM2 CH1捕获功能;  

4.捕获到上升沿后,定时器当前计数值存入capture_buf[0],改为捕获下降沿;   

5.捕获到下降沿后,定时器当前计数值存入存入capture_buf[1],关闭TIM2 CH1捕获功能;  capture_Cnt=3;

6.  高电平时间: capture_buf[1] - capture_buf[0]        发送到上位机  重新启动输入捕获


__HAL_TIM_SET_COUNTER(&TIM5_Handler,0);   //设置计数寄存器的值变为0

HAL_TIM_PWM_Start()              函数用于使能定时器某一通道的PWM输出。

HAL_TIM_IC_Start_IT()                  函数用于使能定时器某一通道的输入捕获功能,并使能相应的中断

HAL_TIM_IC_Stop_IT()                 函数和开启功能相反,是关闭定时器某一通道的输入捕获功能和相应中断

__HAL_TIM_SET_CAPTUREPOLARITY
不是函数,而是底层操作的一个宏定义

在stm32f4xx_hal_tim.h文件中可以找到。其作用是修改定时器某一通道的输入捕获极性

20190813171232499.png

其中有两个函数,第一个为清除清除原来的捕获极性,第二个为设置通道捕捉极性

等价于:

  1. TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1);   //一定要先清除原来的捕获极性!!
  2. TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//定时器5通道1设置为下降沿捕获(重设捕获极性)
复制代码

在修改定时器某一通道的输入捕获极性时,一定要先清除该通道之前捕获极性

__HAL_TIM_GET_COMPARE也是一个宏定义。 
在stm32f4xx_hal_tim.h文件中可以找到。其作用是获取定时器某一通道的捕获/比较寄存器值

20190813171323391.png

等价于 :  HAL_TIM_ReadCapturedValue(&htim5,TIM_CHANNEL_1);

  两者都是直接读取对应CCRx寄存器的值



收藏 评论0 发布时间:2022-3-25 10:29

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版