打印

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

[复制链接]
3882|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中的几句话好用

使用特权

评论回复
5
咫尺天涯33| | 2017-5-10 13:19 | 只看该作者
提供一个笨办法  读取当前计数值 (TIM_GetCounter(TIM1) 如果数字比较大  那么就是上溢出  如果数字比较小就是下溢出  前提是中心对称计数方式

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

25

帖子

1

粉丝