电子产业一站式赋能平台

PCB联盟网

搜索
查看: 36|回复: 0
收起左侧

STM32CubeMX之定时器输入捕获

[复制链接]

454

主题

454

帖子

2396

积分

三级会员

Rank: 3Rank: 3

积分
2396
发表于 2020-3-12 21:45:00 | 显示全部楼层 |阅读模式
上一章介绍了STM32定时器的PWM输出功能,定时器的几个通道除了有输出功能外,还可以做输入用,可捕获信号的上升沿或下降沿,可以用于测量信号的频率、周期、占空比等。本篇文章将介绍用STM32的定时器输入捕获功能测量方波的频率。前期准备
  • STM32硬件电路板及仿真器(以STM32F072C8单片机为例)
  • Keil v5以上版本(MDK-ARM)
  • 信号发生器

    测量频率的原理是用定时器的捕获功能捕获信号的上升沿,并用定时器的定时功能统计两次捕获之间的时间(两次捕获时计数器的差值/定时器的频率),即为信号的周期,周期的倒数即为频率。
    STM32CubeMX配置
    首先新建工程后,配置系统时钟为48MHz(参考之前的文章STM32CubeMX之GPIO的使用)。以TIM1为例,使能TIM1的时钟源为Internal Clock(即48MHz系统时钟),设置通道1为Input Capture direct mode,可以看到对应到PA8引脚自动被设置为TIM1_CH1功能。定时器基本参数的配置参考STM32CubeMx之TIM定时中断,其它具体配置如下图。

    3ftqd4b5gzr64048945732.jpg

    3ftqd4b5gzr64048945732.jpg

    STM32的定时器通道可以设置上升沿捕获、下降沿捕获或者上升沿下降沿都捕获。当捕获到信号的上升沿或下降沿时,产生一个捕获中断。这里设置为上升沿捕获。其中Prescaler Division ratio参数为可预置分频比,可设置为不分频或2/4/8分频,若设置为2分频,表示捕获到2个上升沿才产生一次中断。Input Filter为输入滤波器参数,滤波器的功能简单来说就是多次检测视为一次有效,也就是说连续N次采样检测,如果都是高电平,则说明这是一个有效的电平信号,这样便可以过滤掉那些因为某些而干扰产生的一些信号。设置完成后,打开定时器的溢出中断和捕获中断。

    jaiitlemun564048945832.png

    jaiitlemun564048945832.png

    之所以需要打开溢出中断,是因为两次捕获之间,定时器可能会溢出,需要在中断中记录溢出次数,才能统计两次捕获之间的总时间。点击 Generate Code生成代码。程序编写
    在初始化后添加以下代码:
  •   HAL_TIM_Base_Start_IT(&htim1);//启动定时器1中断  HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_1);//开启定时器1通道1捕获中断编写两个中断回调函数,定时器溢出中断用于统计溢出次数,在捕获中断中记录当前的捕获值,两次捕获的总计数值=溢出次数*65535+两次捕获的差值。程序如下:
  • uint32_t TIM1_Over_Cnt=0;//溢出次数计数uint8_t TIM1_Cap_Flag=0;//捕获标志0 表示第一次捕获  1表示第二次捕获uint32_t TIM1_Cap_Value[2]={0,0};//两次捕获的定时器计数值uint32_t TIM1_Counter=0;//两次捕获的计数差值//定时器溢出中断回调函数void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){    if (htim == (&htim1))    {        TIM1_Over_Cnt++;//溢出次数+1    }}
    //定时器捕获中断void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){
      if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)  {    if(TIM1_Cap_Flag==0 )//上次测量值已经处理完,第一次捕获    {      TIM1_Cap_Flag=1;      TIM1_Cap_Value[0]=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);      TIM1_Over_Cnt=0;    }    else if(TIM1_Cap_Flag==1)//第2次捕获    {          TIM1_Cap_Value[1]=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);        TIM1_Counter = (TIM1_Over_Cnt16) + TIM1_Cap_Value[1] - TIM1_Cap_Value[0];//溢出次数        TIM1_Cap_Flag=2;//两次捕获完成 开始计算    }  }}第二次捕获完成后,可以计算信号的频率:
  •     if(TIM1_Cap_Flag==2)//通道1捕获完成标志    {      Frequence = (float)48000000 / TIM1_Counter;      TIM1_Cap_Flag = 0;//重新开始下次捕获标志    }采用这种计数方式测量频率属于测周法(测量周期),存在±1误差,当信号的频率较高时,TIM1_Counter值会变小,±1误差的影响将会被放大。因此,被测信号的频率越高,这种方法的测量误差越大。
    另外一种方法为测频法,用定时器设定一个确定的闸门时间(比如1秒),在1秒内记录捕获到的上升沿的次数。捕获次数/闸门时间即为被测信号的频率。这种方式同样存在±1误差,被测信号频率越低,误差的影响就越大。两种方法互补,工程师可根据被测信号的频率范围决定使用哪种方法。下一章将介绍另外一种频率测量的方法,等精度测频。顾名思义,该方法的测量误差不受被测信号的影响,在全频率段内精度一致。
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表