极客秀
搜索

STM32CubeMX输入捕获测周法检测频率

STM32统计频率有许多种方式,有使用外部中断+定时器的方法,但是还有一种更加准确,可以计算占空比的方法。
即使用输入捕获来统计。
输入捕获的基本原理是通过检测TIMx_CHx上的边沿信号(如上升沿或下降沿),在边沿信号发生跳变时,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中,从而完成一次捕获。此外,还可以配置捕获时是否触发中断或DMA等。
我们可以配置一个外部中断的中断回调函数,在中断回调函数中,我们可以计算两个脉冲的时间差来准确的计算脉冲的周期(频率)

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

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

触发方式选择上升沿触发,这边定时器分频系数选择150-1,1us计数一次,最高计数65535即计数时间65.53ms,对应的最低频率为15HZ。
最高计数频率为1us即100KHZ,滤波系数选择0(因为不是按键没有杂波)

开启定时器中断。
这里的中断触发有两种可能:第一是计数器溢出导致的中断触发,第二种是检测到上升下降沿导致的中断触发。
由于我们的测量频率在我们的计数频率之内,所以我们不考虑计数溢出导致的中断触发。 这里分频系数也不能太高,我就干脆不分频了。 因为等会我们会清除计数器


struct Pre{  float HighTime;//高电平时间  float LowTime;//低电平时间  uint8_t CapStatus;//计算是否是第二次捕获  float Frequent;//频率值  float Time;  uint8_t EndFlag;//捕获结束  float Duty;//占空比};  
  
void GetFreq(struct Pre*pre,TIM_HandleTypeDef * htim,uint32_t Channel){    if(!pre->EndFlag)    {      if(pre->CapStatus == 0)        //第一个上升沿         {           pre->CapStatus = 1;           __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel, TIM_INPUTCHANNELPOLARITY_FALLING); //设置成下降沿触发           __HAL_TIM_SetCounter(htim, 0);    //清空定时器计数值           pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //由第一个上升沿设为起始位置           }else if(pre->CapStatus == 1)    //第一个下降沿          {             pre->CapStatus = 2;             pre->LowTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //低电平起始位置             __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel,TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿触发          }else if(pre->CapStatus == 2)    //第二个上升沿          {          pre->CapStatus = 0;          pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);          //计算频率          pre->Frequent = 1/pre->HighTime*100000;          //计算占空比          pre->Duty = (float)pre->LowTime / (pre->HighTime+1);          pre->EndFlag = 1;          }    }  
}

我们定义一个结构体存放计数值和频率值,之后写一个函数来计算频率值。
主要统计两个上升沿之间的时间。


    HAL_TIM_Base_Start_IT(&htim16);    HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);    __HAL_TIM_ENABLE_IT(&htim16,TIM_IT_UPDATE);    //一定要开启TIM16的更新中断      HAL_TIM_Base_Start_IT(&htim8);    HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);    __HAL_TIM_ENABLE_IT(&htim8,TIM_IT_UPDATE);    //一定要开启TIM8的更新中断

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


void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){  if(htim==&htim8)  {    GetFreq(&pre1,htim,TIM_CHANNEL_1);  }}

输入捕获到频率检测。


      if(pre1.EndFlag)      {        sprintf(pr,"FreQuent:%.2f",pre1.Frequent);        LCD_DisplayStringLine(Line4,pr);        pre1.EndFlag = 0;      }

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

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

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

1.转载请保留原文链接谢谢!
2.本站所有资源文章出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。
3.本站发布资源来源于互联网,可能存在水印或者引流等信息,请用户擦亮眼睛自行鉴别,做一个有主见和判断力的用户。
4.本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。
5.联系方式(#替换成@):pm#vimge.com

  相关内容