STM32
直播中

吴湛

10年用户 922经验值
擅长:电源/新能源
私信 关注
[问答]

STM32测量外部输入信号的频率的方法有哪几种?

STM32测量外部输入信号的频率的方法有哪几种?

回帖(1)

刘鑫

2021-11-25 10:00:57
STM32测量外部输入信号的频率的方法有很多:




  • 采用内部定时器输入捕获功能。
  • 采用普通的IO口设置外部中断+定时器的当时测量PWM信号的频率。

    这两种方式比较推荐使用第一种,比较使用内部的资源可以节省CPU资源的利用,
    当然当内部资源不够使用的时候,或者是说,硬件威廉希尔官方网站 设计的时候没有连接相应的应引脚只能使用第二种方式了。

    本次由于硬件威廉希尔官方网站 设计的不足,导致需要测量PWM输入信号的引脚没有接到相应的通道上,对此使用了第二种方式:
      注意:这里定时器中断的优先级要高于外部中断的优先级

思路如下:




  • 设置PWM输入信号的引脚为外部中断的方式,并且触发方式为GPIO_MODE_IT_RISING_FALLING 上升,下降沿均可触发。
  • 其次使能一个定时器TIM4,定时中断时间看自己需要测量频率来设置。(本次设置为2us –> 最大可测量的频率为50KHz)
  • 外部中断中,上升沿到来,清空计数器TIM4->CNT=0,置一个上升沿的标志位为1,代表计算PWM时间的开始tim4_PWM_cnt++。
  • 下降沿到来,置一个下降沿的标志为1.
  • 下一次上升沿到来,判断上一次是否为下降沿的标志,如果是,则代表PWM一个周期的时间已经到达。读取时间。PWM_Cycle = timer4_PWM_cnt*2. 并且把计数变量清零tim4_PWM_cnt = 0
  • 接着下一次下降沿到来,判断上一次是否为上升沿的标志,如果是,则代表一个周期高电平结束,读取时间,即为脉宽 PWM_Duty = timer4_PWM_cnt*2。

    具体c语言实现代码如下:


if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_11) != RESET)
{                           
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);//调用中断处理公用函数  
    if(PWM_EN()==1)     //上升沿触发
    {
        TIM4->CNT=0;//这里清空TIM4计数。重新开始计数
        if((PWM_FLAG_DOWM==1)&&(PWM_FLAG_UP==2))//判断上一次是否为下降沿
        {
            PWM_Cycle = timer4_PWM_cnt*2;
            timer4_PWM_cnt=0;
        }
        PWM_FLAG_CNT = 1;


        PWM_FLAG_UP = 1;//上升沿标志
        PWM_FLAG_DOWM = 2;//上升沿标志
    }
    else//下降沿触发
    {
      if((PWM_FLAG_DOWM==2)&&(PWM_FLAG_UP == 1))//下降沿判断上一个状态是否为上升沿
      {
        PWM_Duty = timer4_PWM_cnt*2;
      }
     PWM_FLAG_DOWM=1;//下降沿标志
     PWM_FLAG_UP=2;//下降沿标志
}
void TIM4_Init(u16 arr,u16 psc)
{  
    TIM4_Handler.Instance=TIM4;                                 //通用定时器4
    TIM4_Handler.Init.Prescaler=psc;                            //分频系数
    TIM4_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;           //向上计数器
    TIM4_Handler.Init.Period=arr;                               //自动装载值
    TIM4_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1; //时钟分频因子
    HAL_TIM_Base_Init(&TIM4_Handler);
    HAL_TIM_Base_Start_IT(&TIM4_Handler);//使能定时器4和定时器4更新中断:TIM_IT_UPDATE   
}


void TIM4_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&TIM4_Handler);
    if(PWM_FLAG_CNT == 1)//PWM上升沿到来标志
    {
        timer4_PWM_cnt++;
    }
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分