手头的旋转编码器为20格一定位一脉冲,在静止的时候AB两线输出都是高电平。转动一格,AB两线各自输出一个低电平脉冲,然后又回到高电平状态。对应于EC11内部AB两个触点开关的动作为断开–>闭合–>断开。通过区分哪根线先触发低脉冲来判断顺时针旋转(正转),逆时针旋转(反转)。下图是时序图,但与我用的可能不是一个型号,时序有出入。也可能是我错了,请大家帮忙指正谢谢大家。
看网上资料有大佬利用逻辑分析仪,将A线作为时钟,B线作为data线,将扭动的脉冲信号,转换成了通讯协议的方式,检测时钟线的触发边沿时,数据线的高低电平判断正反转。还有的前辈轮询检测两根线的电平状态,并将当前状态与上一时刻状态对比的方法判断正反转。
而我看的这个程序很奇怪
#define READ_EN_B() GPIO_ReadInputDataBit(GPIOC,EN_B)
#define READ_EN_A() GPIO_ReadInputDataBit(GPIOC,EN_A)
#define READ_EN_SW() GPIO_ReadInputDataBit(GPIOC,EN_SW)
static u8 deb1=0,deb2=0,kpressed1=0,kpressed2=0; //deb是给sw和en_sw做去抖动的延时,kpressed是二者开闭状态的标志位
static u16 k_hold1=0,k_hold2=0; //按键长按计数,便于确定按下时间
static u8 rise_debounce=0,fall_debounce=0,edge=0; //edge为0表明旋转编码开关被扭动
static u16 RCSfreetime=0,ModeChgTime=0; //RCSfreetime是编码开关空闲时间,ModeChgTime是模式切换时间
// 编码开关识别程序(扭动部分)
if(READ_EN_B() )
{
if(rise_debounce==10) //延时10ms
{
if(!edge)
{
edge=1;
fall_debounce=0;
if(!READ_EN_A()) //顺时针
{
if(sw_conf == 0) //编码开关被按下
{
if(ModeChgTime <= 10) //这是个大概的值,到这个值的范围就可以了
{
RunBuz=1;
if(SysMode==0) //当为电压档时下一次顺时针旋转还是为电压档
{
SysMode=0;
RunBuz=0; //超了就不发声了
}
else
SysMode--;
ModeChgTime = 250; //每次编码开关旋转一次都要等到250ms之后才能检测到第二次旋转,防止抖动造成的窜动
}
}
sw_inc=1;
sw_dec=0;
encoder_speed++;
Sleep_Time = 0; //任何按键一动,睡眠时间就清零
}
if(READ_EN_A()) //逆时针
{
if(sw_conf == 0) //编码开关被按下
{
if(ModeChgTime <= 10)
{
RunBuz=1;
SysMode++;
if(SysMode==4)
{
SysMode=3;
RunBuz=0;
}
ModeChgTime = 250;
}
}
sw_inc=0;
sw_dec=1;
encoder_speed++;
Sleep_Time = 0;
}
}
}
else
rise_debounce++;
}
if(!READ_EN_B()))
{
if(fall_debounce==10)
{
if(edge)
{
edge=0;
rise_debounce=0;
}
}
else
fall_debounce++;
}
因为上电后AB为高电平怎么上来就检测B是否为高电平,这样上电必会误触发。经过一番琢磨,发现思路很巧妙。初始edge=0,会误触一次,但是刚上电会有一段时间对扭动操作进行屏蔽。此时第一次误触就结束了,并且会使edge = 1。扭动检测开始其实是在后面检测B为低电平,只有这样才会使edge = 0。这样在检测到B为高电平时,如果之前没有触发过低脉冲就不会继续进行判断。B触发低脉冲以后,当B恢复为高电平时,通过检测A的电平就可以知道A是否滞后于B,就能判断是正转和反转了。这样做好处是不需要检测边沿,只用io口读取电平的函数,利用前后台系统就可以精准检测了。
这是我利用串口打印得出的扭动过程中AB两线电平变化,不同型号或许有差别(AB 两位表示同一时刻二者的电平)
顺时针:11 10(b为0时edge=0) 00 01(b为1时a为0) 11 11(恢复)
逆时针:11 01 00(b为0时edge=0) 10 11(b为1时a为1) 11(恢复)
如上,只要做好去抖,在合适时间检测AB的电平就可以精准检测扭动了。如果顺时针动作时,对A电平的检测稍晚一些,就会错过其低电平的状态,误判为逆时针扭动,实际使用要考虑到快速转动等情况。