STM32F4系列HAL库配置定时器实验——输入捕获

输入捕获简单讲解

输入捕获模式可以用来测量脉冲宽度或者测量频率。我们以测量周期和频率为例,用一个简图来说明输入捕获的原理

假定定时器工作在向上计数模式,
图中 t1~t2 时间,就是我们需要测量的高电平时间。测量方法如下:首先设置定时器通道 x 为
上升沿捕获,这样,t1 时刻,就会捕获到当前的 CNT 值,然后立即清零 CNT,并设置通道 x为下降沿捕获,这样到 t2 时刻,又会发生捕获事件,得到此时的 CNT 值,记为 CCRx2。这样,根据定时器的计数频率,我们就可以算出 t1~t2 的时间,从而得到高电平脉宽。
在 t1~t2 之间,可能产生 N 次定时器溢出,这就要求我们对定时器溢出,做处理,防止高电平太长,导致数据不准确。如图15.1.1所示,t1~t2之间,CNT计数的次数等于:N*ARR+CCRx2,
有了这个计数次数,再乘以 CNT 的计数周期,即可得到 t2-t1 的时间长度,即高电平持续时间。
输入捕获的原理,我们就介绍到这。
STM32F4 的定时器,除了 TIM6 和 TIM7(这些是基本定时器),其他定时器都有输入捕获功能。STM32F4 的输入捕获,简单的说就是通过检测 TIMx_CHx 上的边沿信号,在边沿信号发生跳变(比如上升沿
/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA 等。

你可以用输入捕获通道来检测信号发生器的,也可以用其他定时器输出PWM。

PWM

我记得PWM我是没有写的,这里简单提一下,其实就是再之前定时器配置的时候加一个CCR,通过ARR与CCR的值的比较选择引脚输出高低电平。

如下图:

我们在配置PWM时无非就是在CUBEmx里多了一个Pulse(脉宽)设置:

PULSE我设置为5,为ARR+1的一半,那么占空比为50%。
图中选择的是PWM1模式,即小于CCR时输出高电平,其余默认即可:
使能CCR寄存器的预装载功能
关闭快速输出模式
输出有效电平为高电平

由于STM32F4的最大时钟频率为84Mhz,那么,我设置的PWM的频率为84000000/(84*(9+1))=100KHZ,周期为1/100000s。

通用定时器可以用来输入捕获,我们用通用定时器即可

输入捕获HAL库配置

我们用两个定时器,一个用来输出PWM,一个用来输入捕获。
1.选芯片就不用我多说了,我选择的是STM32F401CCU6,因为我在Clion上编写时用F4很方便,STlink直接烧写进去,不用我不停动BOOT设置。

2.配置时钟,串口,STM32F4CCU6可以达到最大84MHz的输出



3.配置生成PWM定时器以及输入捕获定时器

这里我用TIM3生成我之前提到的相同频率的PWM,一个定时器可以输出多通道的PWM,我们任选其一生成即可,使用内部时钟(打勾)
之后,我们用TIM2的通道1输入捕获,同样内部时钟打勾

参数设置如下:

别忘了我们还要使能中断,在中断里进行计算

点击代码生成即可。
个人还是强推Clion,不久前才接触,他的代码补全和界面都比较高大上,这里给大家稚晖君的教程优雅的嵌入式开发
还有一个我们院的大佬的教程CLION配置

相关代码

鉴于大部分社区里直接给的代码连解释都不解释一下,很影响我们新手学习,
看到陌生的代码,人一般都愣一下:

这里我把我之前学习的关于这部分函数的视频给大家:MOOC
明确一下我们要使用的函数:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//输入捕获回调函数HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);//输入捕获中断开启HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);//pwm定时器开启HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1);//输入捕获中断关闭uint32_t HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel)

那我们怎么去测呢?我们读到的值是捕获到上升沿的计数值,连续读两次,相减的值就是这段时间的计数值,而我们时钟也是一整段时间的计数值,用总计数值84000000/diff,不就是频率吗?将这个频率倒过来就是信号周期。


整个过程用前后台编程的思想,分工,主函数里显示计算,中断里读值,读两下,算一下。我们设置两个标志位,用于相互判断,这里计算输出完后才能再次捕获,两次捕获完之后才能计算输出。并且两次捕获依次进行。根据这样我们设置变量。

/* USER CODE BEGIN PV */
uint32_t DIff=0;//差值
uint8_t CaptureIndex=0;//捕获标志位
uint8_t MeasureFlag=0;//测量计算标志位
uint32_t CapVal1=0;//捕获值1
uint32_t CapVal2=0;//捕获值2
/* USER CODE END PV */

接下来主函数while中

if(MeasureFlag==1)//测量位判断
{if(CapVal2>=CapVal1)//注意这里分两种情况{DIff=CapVal2-CapVal1;}else{DIff=((4294967295+1-CapVal1)+CapVal2);//这种情况在捕获值1在一个计数周期的结束,而捕获值2是下个计数周期的开始}UART_printf(&huart1,"DIFF=%.8f\r\n",DIff/1.0);UART_printf(&huart1,"Period=%.8fs\r\n",DIff/84000000.0);UART_printf(&huart1,"Fred=%dHz\r\n",84000000/DIff);UART_printf(&huart1,"\r\n");MeasureFlag=0;//置位测量标志位HAL_Delay(1000);HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);//再次开启下次捕获
}}

中断函数里捕获

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM2)
{if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1)//两次判断{if(CaptureIndex==0)//捕获标志位判断{CapVal1= HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//读捕获值1CaptureIndex=1;//捕获标志位=1}else if(CaptureIndex==1)//连续读值{CapVal2= HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);CaptureIndex=0;//捕获标志位置位MeasureFlag=1;//测量标志位置1HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1);//关闭中断}else{Error_Handler();//错误处理}}
}
}

串口重定向里使用,因为Clion里没有使用之前的Microlib库,所以必须换一个函数来重定向,加入#include "stdio.h" #include "stdarg.h"
以及

/* USER CODE BEGIN 0 */
int UART_printf(UART_HandleTypeDef *huart, const char *fmt, ...)
{va_list ap;va_start(ap, fmt);int length;char buffer[128];length = vsnprintf(buffer, 128, fmt, ap);HAL_UART_Transmit(huart, (uint8_t *)buffer, length, HAL_MAX_DELAY);va_end(ap);return length;
}
/* USER CODE END 0 */

这个重定向代码很神奇,在MSP432里也可以使用,甚至我在用串口屏也是用到了,有机会研究一下,或者有大佬可以给我留言讲解一下。


之后我们根据cubemx里的图接线(PA0-PA6,usart-USB转TTL),直接烧录。

和我们TIM3的PWM的设置是一样的。

STM32F4系列HAL库配置定时器实验——输入捕获相关推荐

  1. STM32F1系列HAL库配置系统时钟

    STM32F1系列HAL库配置系统时钟 其实一开始对于时钟我也是知之甚少,在MSP432中我就一直忽视时钟配置,其实也是在STM32学习时落下的病根,现在趁有空补一下. 时钟简单讲解 对于时钟系统,在 ...

  2. HAL库配置GPIO

    HAL库配置GPIO HAL库与标准库不同的特点: 使用`CubeMX`配置GPIO底层参数: 总结HAL库中GPIO的相关功能: GPIO的寄存器: 总结 HAL库与标准库不同的特点: 标准库中初始 ...

  3. STM32CubeMX | STM32 F1系列HAL库低功耗STOP和STANDBY模式唤醒(RTC时钟唤醒+外部中断唤醒示例)

    STM32CubeMX | STM32 F1系列HAL库低功耗STOP和STANDBY模式唤醒(RTC时钟唤醒+外部中断唤醒示例) 目录 STM32CubeMX | STM32 F1系列HAL库低功耗 ...

  4. STM32 学习笔记 -- 基于stm32f4的看门狗配置和实验代码

    基于stm32f4的看门狗配置和实验代码 以下本人对stm32f4xx的独立看门狗和窗口看门狗学习.理解和总结,程序的说明和解释均在注释中,仔细阅读不难理解.我已经过验证,有问题或错误请指出. 版权声 ...

  5. HAL库配置FreeRTOS

    HAL库配置 配置时钟源 1:修改HAL库定时器时钟源. 由于HAL库内部会使用systick定时器用于系统延时功能,而FreeRTOS也需要一个定时器用于操作系统内核调度的使用,顾需修改HAL库的时 ...

  6. 【WB32库开发】第12章(上)TIM1高级定时器——PWM输入捕获

    本章要学习的PWM输入捕获是定时器又一重要应用,使用PWM输入捕获可以测量输入PWM的频率和占空比. PWM输入只能使用定时器的两个通道:通道1和通道2,且一路PWM输入要占用两个捕获寄存器,一个用于 ...

  7. STM32系列(HAL库)——F103C8T6通过MFRC522、RFID射频卡、门禁卡模块读取卡片ID(二)

    本文继上一篇:STM32系列(HAL库)--F103C8T6通过MFRC522.RFID射频卡.门禁卡模块读取卡片ID 本文介绍在运用RC522模块时,运用链表结构存储数据的操作 Let's go! ...

  8. STM8SF903K3T6定时器1输入捕获

    STM8SF903K3T6定时器1输入捕获 简介 最近接了个转速仪的项目,原理是计频率.最开始是用外部中断,然后根据定时器定时一秒来取值,转速是rpm,所以还要乘以60. 因为需要反映快所以后来改用定 ...

  9. STM32F4 (hal库)ADC+TIM1+DAC的配置

    写在前面:感谢XXX大佬的指导,点击可查看他的博客 实现的功能: 用定时器TIM产生PWM波来控制ADC的采样频率,在ADC中断中将采样值直接通过DAC输出.本文主要展示ADC.TIM.DAC的配置( ...

最新文章

  1. 《 Java并发编程从入门到精通》Thread安全与不安全
  2. JMJS系统总结系列----Jquery分页扩展库(五)
  3. 最适合做老婆主播不是Rita?不是豚豚,也不是纪小鹿,是她
  4. 带头节点循环链表实现队列
  5. 2019 年被“杀”死的那些技术!
  6. 用python画多来a梦-python3里tkinter中canvas(画板)案例之哆啦A梦
  7. Unity HTC Vive手柄汉诺塔操作
  8. python什么叫索引_python中索引是什么意思(一文详解其定义)
  9. 小觅相机运行VINS-Fusion(二)——Camera-IMU参数标定
  10. 高速扩张的云市场,需要怎样的安全能力?
  11. 什么是集群?什么又是负载均衡?你未必说的清楚
  12. 求助,WIN10系统,我的推特用不了,提示网络没连接,其实我网络是好的,求大神指点,万分感谢!
  13. 如何使用Dareboost改善网站性能(和转化)
  14. MySQL 正负数排序
  15. noip2010引水入城-搜索+贪心
  16. BadUSB+ProMicro+Arduino做一个插入U盘自动攻击
  17. 夜神模拟 配置 热加载
  18. 计算机网络:数据链路层:有线和无线网络(4)
  19. python中的max_row_基于row max定位条件列值
  20. 智能运维案例系列 | 新网银行 X 袋鼠云:银行核心业务系统日志监控平台建设实践...

热门文章

  1. JAVA猜数字 斗地主小游戏
  2. map集合之——应用:斗地主小游戏之发牌
  3. 思科CCNA EIGRP
  4. 爬虫之Scrapy框架爬取彼岸壁纸案例分享
  5. 区块链国际政策影响及国内发展趋势分析
  6. qt如何编译以及设计手机APP------为女朋友设计的APP 初级
  7. 使用jira管理Scrum敏捷项目实战(三)jira自定义工作流
  8. 【MySQL】MySQL如何合并多行数据,行转列,group_concat 多行合并
  9. 理解:用变分推断统一理解深度生成模型(VAE、GAN、AAE、ALI(BiGAN))
  10. win10 桌面显示 计算机,win10我的电脑在哪里?win10桌面显示我的电脑方法