This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430G2553:旋转编码器方向

Guru**** 2577385 points
Other Parts Discussed in Thread: MSP430G2553

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/608950/msp430g2553-rotary-encoder-direction

器件型号:MSP430G2553

大家好、

我使用的是两相正交增量旋转编码器、具有集电极开路 NPN 输出和每转600个脉冲。 我正在检测端口1.2和1.4上的 A 和 B 值。  该程序如下所示、

#include

#define PHASEA BIT2
#define PHASEB BIT4

Int 顺时针;
逆时针;

void update (void);

int main (空)

WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时器

顺时针= 0;
逆时针= 0;

P1DIR &=~Ω(PHASEA + PHASEB);//将 P1.2和 P1.4设置为输入
P1IFG &=~(PHASEA);//清除 P1.2的中断标志  

P1IE |= PHASEA;// 启用 P1.2中断
P1IES &=~PHASEA;//在上升沿产生中断
_ENABLE_INTERRUPT ();//启用所有中断


#pragma vector=Port1_vector
_interrupt void Port_1 (void)

IF (PHASEA!= PHASEB)

{顺时针++;}

否则 {逆时针++;}

P1IFG = 0;

当编码器轴顺时针旋转360度时、 顺时针可变表示 精确计数为600。 但是 ,当逆时针方向旋转360度时,顺时针方向可变显示为1200。逆时针方向可变,但顺时针方向可变。是否有任何建议?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    除了不正确之外、这是一种使用正交编码器的非常糟糕的方法。 忽略正交部分和全部。 我的代码在两 个输入的上升沿和下降沿都使用中断。 它要复杂得多、但对所有边沿进行计数。

    如果比较不是常数且总是 false 的(位!= BIT4)、则中断例程会更好。 相反、测试(P1IN 和 PHASEB)是0还是1。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 David:

           感谢您的回答。 我的问题是为什么在上升沿和下降沿都使用中断、何时我们可以对仅来自上升沿的脉冲数进行计数?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我同意 PHASEA 和 PHASEB、它们只是定义的恒定值、而不是引脚的当前状态。 测试(P1In & PHASEB)= 0

    但除此之外、我还想知道为什么这不起作用。 首先、您必须假设编码器没有抖动、或者在硬件中进行其他处理。 但是如果这是真的、那么当 Bit2变为高电平并触发中断时、另一个位也是高电平、这表示在一个方向上移动、或者另一个位仍然是低电平、这表示在另一个方向上移动。 似乎这应该起作用、并且应该不需要在任何其他转换上触发中断。

    它是使生活复杂化的肿块反弹。 到目前为止、我在旋转编码器方面的所有经验都是机械开关类型、这种开关会大幅抖动。 但我想600 PPR 类型不会有这个问题。 所以他的方法对我来说似乎是可行的。 否?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    边沿的数量是脉冲的四倍、因此分辨率是原来的四倍。

    我用于用户输入的机械编码器在每个机械锁定位置都有一个边沿。 如果我 只计算脉冲、这意味着每四次点击一次状态改变、这对用户根本没有意义。

     您可以使用更 简单 的软件来解决问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这听起来像是一个有趣的编码器。  我使用的编码器每转的脉冲数与每转的锁定数相同。  因此、在任何两个连续的锁定之间、两个开关都将经历完全关闭/打开循环、并且两个开关都始终在锁定位置打开。  在这种情况下、更简单的代码工作正常、不会丢失分辨率。  另一方面、如果不是一对一的、那么您肯定需要更雄心勃勃的代码、以便能够检测中脉冲发生的情况。  否则、您可以进入下一个锁定点、任何内容都不会显示为咔嗒声。  但我不知道他使用的600 PPR 编码器在哪里适合这种情况。  这将是关键。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 David:

    我更改了中断序列。 在经过特定计数后、需要通过使 P1.6 = 0来停止电机。 即使我已将序列放入 while (1)循环中、电机也不会停止。 有什么建议吗?

    #include "msp430G2553.h"
    定义度(95)
    #define 脉冲(度*2)
    #define PHASEA BIT2
    #define PHASEB BIT4

    int pos;

    signed int required_pulses =脉冲;

    void main (void)

    WDTCTL = WDTPW + WDTHOLD;//停止 WDT

    P1DIR |= BIT5 + BIT6;// p1.5和 P1.6是输出
    P1SEL &=~BIT4;// P1.5是端口,P1.6 至 TA0.1
    P1SEL |= BIT6;
    P1SEL2 &=~BIT4 +~BIT6;

    POS = 0;

    P1DIR &=~Ω(PHASEA + PHASEB);//将 P1.2和 P1.4设置为输入
    P1IFG &=~(PHASEA);//清除 P1.2的中断标志
    P1IE |= PHASEA;//启用 P1.1和 P1.2中断
    P1IES &=~PHASEA;


    TA0CCR0 = 1000-1;//设置最大计数值(PWM 周期)
    TA0CCTL1 = OUTMOD_7;//设置计数器复位时的输出、清除 CCR1上的输出
    TA0CCR1 = 500;//初始化计数器比较值
    TA0CTL = tassel_2 + MC_1;// smclk、upmode


    _ENABLE_INTERRUPT ();//启用所有中断


     while (1)                  //    停止电机  
       {if (pos = required_pulses)
         {P1OUT &=~BIT6;}
        }

    #pragma vector=Port1_vector
    _interrupt void Port_1 (void)

        if (!(P1IN 和 PHASEB))
          { pos--;}

        否则{pos++;}

          P1IFG = 0;