编码器测速原理及实现方法详解

目录:

  • 一、测速原理
  • 二、CubeMX配置编码器模式
  • 三、利用外部中断采集脉冲
  • 一、测速原理

    通常情况下编码器旋转一周会输出固定的脉冲数,即编码器的分辨率,通过测量固定时间T内编码器输出的脉冲数即可求得电机的转速。
    假设编码器的分辨率为P,T时间内测得脉冲数m个,则单倍频(编码器转动一圈输出的脉冲数与分辨率相同)情况下电机转速为:

    (其中m/p为编码器转过的圈数,再除以时间即为转速)
    编码器AB相输出两列相位差为90°的方波,当A相超前于B相90°时为正转,相反,B相超前于A相90°时为反转

    为了提高采样精度,利用软件实现四倍频,即将编码器的分辨率提高4倍。原理图如上,一个小周期内AB两相分别各有一个上升沿和下降沿,只需要在AB两相的每个上升沿、下降沿进行采集,这样就实现了四倍频技术,即如果编码器分辨率为p,则现在编码器转动一圈就可以采集到4p个脉冲

    二、CubeMX配置编码器模式

    stm32的部分定时器有编码器模式,可以直接利用该功能采集编码器脉冲数

    先配置串口,方便后期打印采集的数据


    我这里采用定时器4做测速,选择编码器模式,Encoder Mode选择Encoder Mode T1 and T2,这个模式下将在AB相的上升沿和下降沿进行脉冲技术,即四倍频


    配置一定时器用于定时读取和清空脉冲数,此处设置每500ms读取一次

    打开定时器全局中断


    配置时钟



    打开创建好的工程,在主函数中启动编码器脉冲采集和定时器中断


    重定向

    定时器中断服务函数中读取采集到的脉冲数,TIM2的计数值为0-65535,采用short int类型对其强制类型转换,若TIM2计数器值为0 ~ 32767,则强制转化后的值仍为0 ~ 32767,电机正转;
    若TIM2计数器值为32768 ~ 65535,则强制转化后的值仍为-32768 ~ -1,电机反转;使用一阶滤波减小误差,每次采集的脉冲数保存至new_capturenumber,编码器转动一圈输出4096个脉冲,则new_capturenumber/4096为编码器转动的圈数,最后除以采集时间500ms就得到了电机转速(r/s)

    三、利用外部中断采集脉冲

    有些单片机没有编码器功能,如esp32,我们可以利用外部中断对编码器输出脉冲进行计数

    设置PE11 PE14的外部中断,上升沿、下降沿均触发


    打开全局中断


    配置一定时器每500ms读取一次脉冲值


    打开定时器全局中断


    编码器正反转时,脉冲波形如上图所示,我们可以先定义pulse_num来对脉冲进行计数
    当A相下降沿时,若B相为低电平则为反转,pulse_num减一,若B相为高电平则为正转,pulse_num加一
    当A相上升沿时,若B相为低电平则为正转,pulse_num加一,若B相为高电平则为反转,pulse_num减一
    当B相下降沿时,若A相为低电平则为正转,pulse_num加一,若A相为高电平则为反转,pulse_num减一
    当B相上升沿时,若A相为低电平则为反转,pulse_num减一,若A相为高电平则为正转,pulse_num加一
    即:

    /* USER CODE BEGIN 2 */
    int pulse_num=0;
    /* USER CODE BEGIN 2 */
    void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
    //PE11 - A相发生中断
     if(GPIO_Pin==GPIO_PIN_11){
      //A相下降沿
      if(HAL_GPIO_ReadPin(GPIOE,A_phase_Pin)==0)
      {
        if(HAL_GPIO_ReadPin(GPIOE,B_phase_Pin)==0)
          pulse_num--;
        else
          pulse_num++;
      }
      //A相上升沿
      else
      {
        if(HAL_GPIO_ReadPin(GPIOE,B_phase_Pin)==0)
          pulse_num++;
        else
          pulse_num--;
      }
    }
    
    
    //PE14 - B相发生中断
    else if(GPIO_Pin==GPIO_PIN_14){
      //B相下降沿
      if(HAL_GPIO_ReadPin(GPIOE,B_phase_Pin)==0)
      {
        if(HAL_GPIO_ReadPin(GPIOE,A_phase_Pin)==0)
          pulse_num++;
        else
          pulse_num--;
      }
      //B相上升沿
      else
      {
        if(HAL_GPIO_ReadPin(GPIOE,A_phase_Pin)==0)
          pulse_num--;
        else
          pulse_num++;
      }
    		
    }
    }
    


    最后在定时器中断函数中对采集到的脉冲个数处理,注意需要手动清空pulse_num

    物联沃分享整理
    物联沃-IOTWORD物联网 » 编码器测速原理及实现方法详解

    发表评论