如何读取计数器的计数方向

[复制链接]
4535|4
 楼主| daliny 发表于 2009-9-24 11:47 | 显示全部楼层 |阅读模式
准备利用STM32计数器对编码器的输出脉冲进行计数,并对计数器的溢出次数进行计数,若计数器上溢进行加计数,若计数器下溢进行减计数。这样就需要在计数器溢出时,查看其计数方向,但在厂家提供的库函数中没有查到有此功能的库函数。希望得到大家的帮助。谢谢!
飞刘直上 发表于 2009-12-25 16:47 | 显示全部楼层
顶一下,我也需要知道定时器计数的方向,但还不知道怎么读。
香水城 发表于 2009-12-25 17:11 | 显示全部楼层
没有对应的函数,请直接读取寄存器的位。

定时器计数的方向位是TIMx->CR1的第4位。

if ((TIMx->CR1 & 0x10) !=0)
   // 计数器向下计数
else
  // 计数器向上计数
lxyppc 发表于 2009-12-25 17:25 | 显示全部楼层
贴一个ST电机库中对Encoder处理的代码

/*******************************************************************************
* Function Name  : ENC_Calc_Rot_Speed
* Description    : Compute return latest speed measurement
* Input          : None
* Output         : s16
* Return         : Return motor speed in 0.1 Hz resolution. Since the encoder is
                   used as speed sensor, this routine will return the mechanical
                   speed of the motor (NOT the electrical frequency)
                   Mechanical frequency is equal to electrical frequency/(number
                   of pair poles).
*******************************************************************************/

s16 ENC_Calc_Rot_Speed(void)
{   
  s32 wDelta_angle;
  u16 hEnc_Timer_Overflow_sample_one, hEnc_Timer_Overflow_sample_two;
  u16 hCurrent_angle_sample_one, hCurrent_angle_sample_two;
  signed long long temp;
  s16 haux;
  
  if (!bIs_First_Measurement)
  {
    // 1st reading of overflow counter   
    hEnc_Timer_Overflow_sample_one = hEncoder_Timer_Overflow;
    // 1st reading of encoder timer counter
    hCurrent_angle_sample_one = ENCODER_TIMER->CNT;
    // 2nd reading of overflow counter
    hEnc_Timer_Overflow_sample_two = hEncoder_Timer_Overflow;  
    // 2nd reading of encoder timer counter
    hCurrent_angle_sample_two = ENCODER_TIMER->CNT;      

    // Reset hEncoder_Timer_Overflow and read the counter value for the next
    // measurement
    hEncoder_Timer_Overflow = 0;
    haux = ENCODER_TIMER->CNT;   
   
    if (hEncoder_Timer_Overflow != 0)
    {
      haux = ENCODER_TIMER->CNT;
      hEncoder_Timer_Overflow = 0;            
    }
     
    if (hEnc_Timer_Overflow_sample_one != hEnc_Timer_Overflow_sample_two)
    { //Compare sample 1 & 2 and check if an overflow has been generated right
      //after the reading of encoder timer. If yes, copy sample 2 result in
      //sample 1 for next process
      hCurrent_angle_sample_one = hCurrent_angle_sample_two;
      hEnc_Timer_Overflow_sample_one = hEnc_Timer_Overflow_sample_two;
    }
   
    if ( (ENCODER_TIMER->CR1 & TIM_CounterMode_Down) == TIM_CounterMode_Down)  
    {// encoder timer down-counting
      wDelta_angle = (s32)(hCurrent_angle_sample_one - hPrevious_angle -
                    (hEnc_Timer_Overflow_sample_one) * (4*ENCODER_PPR));
    }
    else  
    {//encoder timer up-counting
      wDelta_angle = (s32)(hCurrent_angle_sample_one - hPrevious_angle +
                    (hEnc_Timer_Overflow_sample_one) * (4*ENCODER_PPR));
    }
   
    // speed computation as delta angle * 1/(speed sempling time)
    temp = (signed long long)(wDelta_angle * SPEED_SAMPLING_FREQ);                                                               
    temp *= 10;  // 0.1 Hz resolution
    temp /= (4*ENCODER_PPR);
        
  } //is first measurement, discard it
  else
  {
    bIs_First_Measurement = FALSE;
    temp = 0;
    hEncoder_Timer_Overflow = 0;
    haux = ENCODER_TIMER->CNT;      
    // Check if Encoder_Timer_Overflow is still zero. In case an overflow IT
    // occured it resets overflow counter and wPWM_Counter_Angular_Velocity
    if (hEncoder_Timer_Overflow != 0)
    {
      haux = ENCODER_TIMER->CNT;
      hEncoder_Timer_Overflow = 0;            
    }
  }
  
  hPrevious_angle = haux;  

  return((s16) temp);
}

写得很长,看着很酷,不过很遗憾,实际使用时不如MicroChip Manul中的几句话好用
咫尺天涯33 发表于 2017-5-10 13:19 | 显示全部楼层
提供一个笨办法  读取当前计数值 (TIM_GetCounter(TIM1) 如果数字比较大  那么就是上溢出  如果数字比较小就是下溢出  前提是中心对称计数方式
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

25

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部