旋转编码器状态机 - 每次中断只能读取两个引脚状态之一

时间:2018-01-10 18:49:19

标签: c# events bit-manipulation state-machine .net-micro-framework

背景:

在阅读this arduino example后,我正在使用状态机为格雷码旋转编码器编写驱动程序。我的设备使用.net微框架用c#编码。由于它不是一个实时的嵌入式操作系统,我只能在中断期间捕获编码器的两个引脚之一的状态。中断时,事件排队等待在高优先级线程中运行。生成中断的引脚状态作为参数传递给“ISR”,即NativeEventHandler代理。在处理程序运行时读取第二个引脚的状态是不准确的,因为它是在实际事件排队后的几毫秒。(我已经尝试过了)

在我的情况下,基本状态是引脚A和B都拉高(值= 1)

所以,我只有4个可测量的状态,但实际状态是基于先前的状态。

  1. Pin A High 1
  2. Pin B High 1
  3. Pin A Low 0
  4. Pin B Low 0
  5. 我在创建状态转换表时遇到问题,表格不会混淆。我试图想出一些快速的逻辑或者可能是一些按位操作来完成这个。

    这是我提出的州表(不是过渡表):

    Pin State   Assigned Value  State Name
    PinB-High   4               CW Rot
    PinA-High   3               CW3
    PinB-Low    2               CW2
    PinA-Low    1               CW1
    Start       0               Start
    PinB-Low    5               CCW1
    PinA-Low    6               CCW2
    PinB-High   7               CCW3
    PinA-High   8               CCW Rot
    

    如何才能获得正确的过渡4个状态?

2 个答案:

答案 0 :(得分:0)

在格雷码中,一次只改变一位,我建议不要将其视为4个状态,而是尝试用逐位表示来思考它。假设PinA为0位,PinB为1位。

由于您说两个引脚都处于基态高电平,因此转换可能是:

CW: b11 -> b01 -> b00 -> b10

CCW: b11 -> b10 -> b00 -> b01

逻辑可能会被翻转,具体取决于编码器的工作方式。

然后您应该可以轻松地使用开关盒来处理它。

答案 1 :(得分:0)

即使考虑每个编码器状态的位对,接触跳动也是如此嘈杂,以至于使用状态机对这些激励进行解码,结果可能是不准确的。状态混合加上某种电容器去抖动和一些与中断功能中引入的触点去抖动时间规格相匹配的延迟可以提供帮助。从一种编码器品牌和型号到另一种编码器品牌,反弹可能会发生很大变化。操作系统中的软件延迟可能会使情况变得更糟。这需要时间和一些测试。