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

【经验分享】STM32Cube HAL 输入捕获——脉宽测量

[复制链接]
STMCU小助手 发布时间:2022-4-7 16:05
实验内容:使用通用定时器输入捕获测量信号的脉宽(检测按键按下的时间)。

一、原理图

S2UQH`KQIB]8QVT9A}}_0GG.png

二、 CubeMX配置

Step1.打开 STM32CubeMX,点击“New Project”,选择芯片型号,STM32F103VETx。

[4{_]0(A0S4UV4[2WDF0{86.png

Step2.选择时钟源,并配置时钟树。选择Crystal/Ceramic Resonator,并配置系统时钟为72M。

P]7Z@[K3G]5A6%@~75XJOXQ.png

@H_}RX(4VA9}FKA~9YD@J@J.png

Step3.配置SYS,我们这里选择的是Serial Wire。(正常情况配置不配置不影响,debug可以使用。但是你不可以把这两个引脚用于其他复用功能,如果用于其他复用功能,debug就不起作用了。)

]ANUD1142)915ZQ$HZ2[5{D.png

Step4.串口配置(主要为了在串口调试助手显示测试的时间),因为没有用到中断和DMA所以我们就不过多讲解。

O[OB9_5BBG`(6FO]751[4TS.png

22I99T3B]AS`RF`{BV)MW%X.png

Step5.接下来进行最主要的定时器配置。原理图中按键引脚PA0和定时器2通道1相关,因此我们选用定时器2进行配置。

6PP9TS]JJ~$(G0)0G[YP~~7.png

PT[JGPZ}N[L(W~E)2{@AL{P.png

到这里关于相关参数配置基本已经完成,只需要根据之前文章《STM32Cube HAL:GPIO输入/输出(一)》Step4-Step8,设置相关工程参数和生成代码。

三、添加功能代码

1、我们等会会向串口调试助手发送数据,进行实验结果的验证。 发送数据我们采用printf函数,所有需要重定向c库函数printf到串口。注意使用时需要在keil设置中勾选微库(use mircolib),同时需要添加头文件#include <stdio.h>。重定向代码如下(usart.c)

  1. //重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
  2. int fputc(int ch, FILE *f)
  3. {
  4.         /* 发送一个字节数据到串口DEBUG_USART */
  5.         HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);        
  6.         
  7.         return (ch);
  8. }

  9. //重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
  10. int fgetc(FILE *f)
  11. {               
  12.         int ch;
  13.         HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 1000);        
  14.         return (ch);
  15. }
复制代码

2、定义相关变量,以及使能相关定时器和计数处理代码(main.c)

  1. //全局变量
  2. uint32_t ccr_cnt,period_cnt;//CCR寄存器值,中断次数
  3. uint8_t tri_flag,end_flag;//触发方式标志位,捕获标记位
复制代码
  1. //局部变量
  2. uint32_t cnt_cl=72000000/72;;//计数器时钟
  3. float time;//按键时间
复制代码
  1. //使能相关定时器以及计数结果处理代码

  2.         __HAL_TIM_CLEAR_FLAG(&htim2,TIM_IT_UPDATE);//清除中断标志位,防止一使能定时器就进入中断
  3.     HAL_TIM_Base_Start_IT(&htim2);//使能定时器及更新中断
  4.         HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);//使能定时器及捕获中断

  5.         printf("\r\n——————————开始按键测试——————————\r\n");
  6.         
  7.   while (1)
  8.   {
  9.                 if(end_flag==1)//结束捕获
  10.                 {
  11.                         time=(float)(period_cnt*1000+(ccr_cnt+1))/cnt_cl;//结果强制转换为浮点型
  12.                         printf( "\r\n测得高电平脉宽时间:%.2fs\r\n",time);//输出结果保留小数点后两位
  13.                         end_flag=0;               
  14.                 }
  15.   }
复制代码


3、中断回调函数(更新中断和捕获中断)(main.c)

  1. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  2. {
  3.         period_cnt++;//中断计数
  4. }
  5. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
  6. {
  7.         
  8.         if(tri_flag==0)//上升沿触发时进入(tri_flag  0 上升沿触发 / 1 下降沿触发)
  9.         {
  10.                 period_cnt=0;//中断次数清零
  11.                 __HAL_TIM_SET_COUNTER(&htim2,0); //计数器清零
  12.                 ccr_cnt=0;//存捕获寄存器获取的值的变量清零
  13.                 __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING);//改变触发极性-下降沿触发
  14.                 tri_flag=1;
  15.         }
  16.         else//下降沿触发时进入
  17.         {
  18.                 ccr_cnt=__HAL_TIM_GET_COMPARE(&htim2, TIM_CHANNEL_1);//获取捕获寄存器的值
  19.                 //ccr_cnt=HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);//功能同上
  20.                 __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);//改变触发极性-上降沿触发
  21.                 tri_flag=0;
  22.                 end_flag=1;//捕获完成标志
  23.         }
  24. }
复制代码


总体来这个实验还算简单,主要的思路是先捕获第一个上升沿,然后将计数器值,中断计数值以及CCR寄存器(存捕获寄存器获取的值的变量)清零,同时变换为下降沿触发,进行第二次捕获,通过第二次的触发获取中断计数值以及CCR寄存器的值来计算出按键按住的时间。


收藏 评论0 发布时间:2022-4-7 16:05

举报

0个回答

所属标签

相似技术帖

官网相关资源

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