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

基于STM32CubeMX输入捕获测周法检测频率经验分享

[复制链接]
攻城狮Melo 发布时间:2024-5-29 17:14
STM32统计频率有许多种方式,有使用外部中断+定时器的方法,但是还有一种更加准确,可以计算占空比的方法。

即使用输入捕获来统计。

输入捕获的基本原理是通过检测TIMx_CHx上的边沿信号(如上升沿或下降沿),在边沿信号发生跳变时,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中,从而完成一次捕获。此外,还可以配置捕获时是否触发中断或DMA等。

我们可以配置一个外部中断的中断回调函数,在中断回调函数中,我们可以计算两个脉冲的时间差来准确的计算脉冲的周期(频率)

微信图片_20240529171352.png

这里我使用蓝桥杯的竞赛平台,STM32G431原理图中有两个NE555产生方波连接至PA15和PB4。

微信图片_20240529171348.png

这里的PB4和PA15分别对应了TIM16的CHANNLE1和TIM8的CHANNLE1。

微信图片_20240529171343.png

触发方式选择上升沿触发,这边定时器分频系数选择150-1,1us计数一次,最高计数65535即计数时间65.53ms,对应的最低频率为15HZ。

最高计数频率为1us即100KHZ,滤波系数选择0(因为不是按键没有杂波)

微信图片_20240529171339.png


开启定时器中断。

这里的中断触发有两种可能:第一是计数器溢出导致的中断触发,第二种是检测到上升下降沿导致的中断触发。

由于我们的测量频率在我们的计数频率之内,所以我们不考虑计数溢出导致的中断触发。

这里分频系数也不能太高,我就干脆不分频了。

因为等会我们会清除计数器

  1. struct Pre
  2. {
  3.   float HighTime;//高电平时间
  4.   float LowTime;//低电平时间
  5.   uint8_t CapStatus;//计算是否是第二次捕获
  6.   float Frequent;//频率值
  7.   float Time;
  8.   uint8_t EndFlag;//捕获结束
  9.   float Duty;//占空比
  10. };




  11. void GetFreq(struct Pre*pre,TIM_HandleTypeDef * htim,uint32_t Channel)
  12. {
  13.     if(!pre->EndFlag)
  14.     {
  15.       if(pre->CapStatus == 0)        //第一个上升沿
  16.          {
  17.            pre->CapStatus = 1;
  18.            __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel, TIM_INPUTCHANNELPOLARITY_FALLING); //设置成下降沿触发
  19.            __HAL_TIM_SetCounter(htim, 0);    //清空定时器计数值
  20.            pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //由第一个上升沿设为起始位置
  21.           }else if(pre->CapStatus == 1)    //第一个下降沿
  22.           {
  23.              pre->CapStatus = 2;
  24.              pre->LowTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //低电平起始位置
  25.              __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel,TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿触发
  26.           }else if(pre->CapStatus == 2)    //第二个上升沿
  27.           {
  28.           pre->CapStatus = 0;
  29.           pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);
  30.           //计算频率
  31.           pre->Frequent = 1/pre->HighTime*100000;
  32.           //计算占空比
  33.           pre->Duty = (float)pre->LowTime / (pre->HighTime+1);
  34.           pre->EndFlag = 1;
  35.           }
  36.     }


  37. }
复制代码

我们定义一个结构体存放计数值和频率值,之后写一个函数来计算频率值。

主要统计两个上升沿之间的时间。

  1.     HAL_TIM_Base_Start_IT(&htim16);
  2.     HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);
  3.     __HAL_TIM_ENABLE_IT(&htim16,TIM_IT_UPDATE);    //一定要开启TIM16的更新中断
  4.       HAL_TIM_Base_Start_IT(&htim8);
  5.     HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);
  6.     __HAL_TIM_ENABLE_IT(&htim8,TIM_IT_UPDATE);    //一定要开启TIM8的更新中断
复制代码

开启定时器计数以及使能中断。

  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
  2. {
  3.   if(htim==&htim8)
  4.   {
  5.     GetFreq(&pre1,htim,TIM_CHANNEL_1);
  6.   }
  7. }
复制代码

输入捕获到频率检测。

  1.       if(pre1.EndFlag)
  2.       {
  3.         sprintf(pr,"FreQuent:%.2f",pre1.Frequent);
  4.         LCD_DisplayStringLine(Line4,pr);
  5.         pre1.EndFlag = 0;
  6.       }
复制代码

如果检测结束则打印频率值。

微信图片_20240529171336.png


微信图片_20240529171330.png


我们可以看到理论最低频率为716.41HZ

微信图片_20240529171326.jpg

可以看到测量最低频率为713.17HZ和理论值的差距非常的小。



转载自:电路小白
如有侵权请联系删除


收藏 评论0 发布时间:2024-5-29 17:14

举报

0个回答

所属标签

相似分享

官网相关资源

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