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

【经验分享】STM32Cube 使用定时器捕获上升/下降沿

[复制链接]
STMCU小助手 发布时间:2022-4-25 21:35
7.5 使用定时器捕获上升/下降沿
7.5.1 配置输入捕获中断引脚

点击“Timers”并选择“TIM2”-“Channel1”将定时器2的通道1选为“Input Capture dirct mode”,使其连接至开发板上的“KEY_UP”按钮。在下方的配置栏中将分频数设为480,得到1MHZ的频率,也就是1us记一次,点击“Counter Period”,再点击右边的齿轮设置,将表达形式设成Hex格式,再将“Counter Period”设置为0xffffffff,这样就支持32位的定时器输入捕获了(部分引脚达不到只能16位)。将捕获方式设为“UP”上升沿捕获,开启自动重置,并将最底下一栏滤波值改为8。

AIA}CD%_~JEE~H`V}H1%A`1.png

在“ NVIC Settings”中将使能中断打开。

34a54f82d0e245dbb4220511edcab145.png

同时进入“GPIO Settings”将该输入捕获引脚设为下拉,保证无信号时能稳定低电平。

NS)5[74G]AC}973OY6~RA5V.png

接着我们需要再设置一个定时器去隔3秒来统计定时器2捕获到的高电平数。

0N@LNC%SP~H61L~E4UHLTYH.png
99246be9906a4e58ba0047ccb7cc7cda.png


将定时器4设为普通定时器来读取捕获数量,分频数为48000得到10KHZ频率,计数30000为3秒,同时开启自动重载防止溢出。同时在“NVIC Setting”中开启全局中断。

288e710fef9f46a2975f501624de4d1e.png

7.5.2 配置串口传输数据

接下来对串口进行配置,将“USART1”打开。并开启USART1全局中断。

690S[L0}C}Y}283}UB(XS~I.png

同时进入“NVIC”中断时序管理页面中,将“USART1”的中断优先度取到3。

UY%QJQ[3MUV)QATD4WMP%NK.png

同时找到PA9和PA10将它们设置为USART1的RXD和TXD引脚,方便USB读取。

WXA_N_PBAP@H7L][Z2_RW7B.png

点击保存并生成代码。

7.5.3 配置定时器捕获代码
首先我们需要重新到“NVIC.h”中添加“usart.h”以及printf和定时器捕获函数的声名。

]Z]{JKMFM1$@`{0D823Z5AF.png

接着到“NVIC.c”文件中添加一些用于储存定时器捕获的缓存变量,并在“NVIC_Init”函数中添加定时器4的初始化用于3秒反馈一次数值。

843d367ceab24d51af03db5039f37938.png

同时添加新的“NVIC_Catch”函数用于在main函数中开启定时器中断并反馈数值。

5051616f1a2d4204a1e87d1109452fbb.png

在定时器反馈函数“HAL_TIM_PeriodElapsedCallback”中添加定时器4的反馈值,使其3秒向串口传输一次数据。
接着再添加一个输入捕获到上升沿的回调函数“HAL_TIM_IC_CaptureCallback”用于对捕获的上升沿信息进行处理并储存至缓存数组中。

852c3002004c42bb9e7ca33868b0a233.png

最后别忘了在Main函数中添加”NVIC_Catch”。

b08dfdc19a2a48a4a5aaad32670aa5ec.png

将程序烧录 至单片机后,将USB MINI线从ST-Link拔下来并连接串口。
由于选用的定时器2通道1串联了按键至3.3V,因此在打开串口后,按“KEY_UP”按键即可手动制造一个上升沿给单片机,并在串口中显示出来。

1bedf058ceec423a81436e26ae82c47e.png

aa622c4635e04924a20978f4301639bd.png

7.5.4 定时器捕获函数介绍
__HAL_TIM_SET_CAPTUREPOLARITY不是函数,而是底层操作的一个宏定义
在stm32H7xx_hal_tim.h文件中找到。其作用是修改定时器某一通道的输入捕获极性

55033751b3da4f5b9bf7d9e2cec54e37.png

其中有两个函数,第一个为清除清除原来的捕获极性,第二个为设置通道捕捉极性
等价于:
TIM_RESET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_1); //清除原来的捕获极性
TIM_SET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//定时器5通道1设置为下降沿捕获(重设捕获极性)
在修改定时器某一通道的输入捕获极性时,一定要先清除该通道之前捕获极性
__HAL_TIM_GET_COMPARE也是一个宏定义。 
在stm32H7xx_hal_tim.h文件中找到。其作用是获取定时器某一通道的捕获寄存器值

6f5222b1246047978446329023cf1b86.png

等价于 : HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
两者都是直接读取对应CCRx寄存器的值。附上程序源码:

  1. #include "main.h"
  2. #include "tim.h"
  3. #include "gpio.h"
  4. #include "usart.h"
  5. #include "stdio.h"
  6. // 重定向printf start
  7. __attribute__((weak)) int _write(int file, char *ptr, int len)
  8. {
  9.          if(HAL_UART_Transmit(&huart1,ptr,len,0xffff) != HAL_OK)
  10.          {
  11.                  Error_Handler();
  12.          }
  13. }
  14. // 重定向printf end
  15. void NVIC_Catch(void);
  16. void NVIC_Init(void);
复制代码
  1. #include "NVIC.h"
  2. static int capture_Buf[3] = {0};   //存放计数值
  3. static int capture_Cnt = 0;    //状态标志位
  4. static int high_time=0;   //高电平时间
  5. void NVIC_Init(){
  6.         HAL_TIM_Base_Start_IT(&htim1);                        //HAL库开启定时器1
  7.         HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);//HAL库开启定时器3,并使用通道4输出PWM
  8.         __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 990);//HAL库修改占空比至99%
  9.         HAL_TIM_Base_Start_IT(&htim4);                        //HAL库开启定时器1
  10. }
复制代码
  1. void NVIC_Catch(){
  2.           switch (capture_Cnt){
  3.                 case 0:
  4.                         capture_Cnt++;
  5.                         __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
  6.                         HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);        //启动输入捕获       或者: __HAL_TIM_ENABLE(&htim2);
  7.                         break;
  8.                 case 3:
  9.                         high_time = capture_Buf[1]- capture_Buf[0];    //高电平时间
  10.                         capture_Cnt = 0;  //清空标志位
  11.                         break;
  12.                 }
  13. }
复制代码


  1. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {        //中断回调函数
  2. if (htim->Instance == htim1.Instance) {                                        //判断是哪个定时器产生中断
  3.         HAL_GPIO_TogglePin(IO_LED0_GPIO_Port, IO_LED0_Pin);        //HAL库控制IO_LED0电平反转
  4. {
  5.          if(TIM2 == htim->Instance)
  6.         {
  7.                 switch(capture_Cnt){
  8.                         case 1:
  9.                                 capture_Buf[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
  10.                                 __HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);  //设置为下降沿捕获
  11.                                 capture_Cnt++;
  12.                                 break;
  13.                         case 2:
  14.                                 capture_Buf[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
  15.                                 HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1); //停止捕获   或者: __HAL_TIM_DISABLE(&htim2);
  16.                                 capture_Cnt++;
  17.                                 break;
  18.                 }
  19. }
  20. }



复制代码


收藏 评论0 发布时间:2022-4-25 21:35

举报

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