在没有正交编码器计数器接口的电路中,对于速度不高的编码器,可以用软件的方式来实现
原理过程参考此文档:编码器四倍频电路的单片机高速算法设计 - 百度文库 (baidu.com)
正交编码器鉴相表
前一个AB相电平状态(ab) | 后一个AB相电平状态(AB) | 拼接成的状态码(二/十六进制) | 对应处理动作 | 输出值 | |
00 | 00 | 0000 | 0x00 | 状态无变化,不处理 | 0 |
00 | 01 | 0001 | 0x01 | 输出反转脉冲Cnt- | -1 |
00 | 10 | 0010 | 0x02 | 输出正转脉冲Cnt+ | +1 |
00 | 11 | 0011 | 0x03 | 异常变化,不处理 | 0 |
01 | 00 | 0100 | 0x04 | 输出正转脉冲Cnt+ | +1 |
01 | 01 | 0101 | 0x05 | 状态无变化,不处理 | 0 |
01 | 10 | 0110 | 0x06 | 异常变化,不处理 | 0 |
01 | 11 | 0111 | 0x07 | 输出反转脉冲Cnt- | -1 |
10 | 00 | 1000 | 0x08 | 输出反转脉冲Cnt- | -1 |
10 | 01 | 1001 | 0x09 | 异常变化,不处理 | 0 |
10 | 10 | 1010 | 0x0A | 状态无变化,不处理 | 0 |
10 | 11 | 1011 | 0x0B | 输出正转脉冲Cnt+ | +1 |
11 | 00 | 1100 | 0x0C | 异常变化,不处理 | 0 |
11 | 01 | 1101 | 0x0D | 输出正转脉冲Cnt+ | +1 |
11 | 10 | 1110 | 0x0E | 输出反转脉冲Cnt- | -1 |
11 | 11 | 1111 | 0x0F | 状态无变化,不处理 | 0 |
unsigned char const EncoderAction[16]={0,-1,1,0, 1,0,0,-1, -1,0,0,1, 0,1,-1,0}; // 每个 a b A B对应的编码动作
int EncCnt=0; //编码器计数值
unsigned char Enc_abAB=0; //编码器相位信号
void DoEncoder2(void)
{
unsigned char AB=0;
Enc_abAB<<=1; //移位操作准备接入新的编码器信号
if(EncA) Enc_abAB|=0x01; // EncA 为编码器接口的A脚电平
Enc_abAB<<=1;
if(EncB) Enc_abAB|=0x01; // EncB 为编码器接口的B脚电平
Enc_abAB&=0x0F;
EncCnt+=EncoderAction[Enc_abAB]; //直接准对状态码做运算
}
void DoEncoder3(void) //另外一种
{
unsigned char AB=0;
Enc_abAB<<=2; //移位操作准备接入新的编码器信号
if(EncA) Enc_abAB|=0x02; // EncA 为编码器接口的A脚电平 若方向反了 此处可调整
if(EncB) Enc_abAB|=0x01; // EncB 为编码器接口的B脚电平
Enc_abAB&=0x0F;
EncCnt+=EncoderAction[Enc_abAB]; //直接准对状态码做运算
}
将上面的函数放入定时中断中运行,以高于编码器实际动作的频率运行,应该就不会丢失动作。
正在测试中。。。