|
发表于 2021-6-27 02:42:42
|
显示全部楼层
本帖最后由 dbxzjq 于 2021-6-27 03:01 编辑
还是这程序精简强大啊!简单几句,一个变量即可解决编码器的正确解码,只要扫描速度够,就非常准确,楼主的程序即使把脉冲的上升沿下降沿都检测了一次,但这程序存在严重的问题,正转时序11 01 00 10 11,如果把反转部分的代码取消掉后,只留下正转这部分的代码,哪么只要反转3格,就会触发一次正转输出return('R');原因是反转的时序11 10 00 01 11 10 00 01 11 10 00 01 11,只要反转三格,刚好可以让正转的检测代码正常进入,首先看
if(EncOld==0x00&&EncNow==0x02||EncOld==0x03&&EncNow==0x01)EncX=EncNow; 01 11 完美配合这一句EncOld==0x03&&EncNow==0x01说=01 11与11 01完全是一样的,因为只是同时比较两个值是不是相等,与实际的编码器转动时的先后顺序不一样啊,程序没了先后顺序的11才到01,与01才到11这个顺序
再当EncNow执行到00后就可以进入一次进行 EncOld=EncNow=00,把旧值更新掉,哪么后面的11 10也同样完全配合到这一句了
if(EncOld==0x00&&EncX==0x02&&EncNow==0x03||EncOld==0x03&&EncX==0x01&&EncNow==0x00)
EncOld==0x00&&EncX==0x02&&EncNow==0x03 00 10 11
这是严重的时序移动的错误
代码修改为如下可以解决此问题,不过这代码得非常高的扫描频率才可以在快速转动时不丢步,因为这代码得扫描多次才完成上升沿和下降沿的检测
static Enc_IF0=0,Enc_IF1=0;
static unsigned char Enc_Old,Enc_Ago=0,dir=0;
unsigned char Enc_Now;
if(Enc_Old != Enc_Now)
{
if(Enc_Old == 0x03 && Enc_Now == 0x01)
dir=1;
else if(Enc_Old == 0x03 && Enc_Now == 0x02)
dir=0;
if(dir)
{
if(Enc_Old == 0x00 && Enc_Now == 0x02 || Enc_Old == 0x03 && Enc_Now == 0x01) Enc_Ago = Enc_Now;
if(Enc_Old == 0x00 && Enc_Ago == 0x02 && Enc_Now == 0x03 || Enc_Old == 0x03 && Enc_Ago == 0x01 && Enc_Now == 0x00)
{
Enc_Old = Enc_Now;
if(EC11_Type == 1)
{
ScanResult =1;
}
else
{
if(Enc_IF1 == 0) Enc_IF1=1;
else
{
Enc_IF1=0;
ScanResult =1;
}
}
}
}
else
{
if(Enc_Old == 0x00 && Enc_Now == 0x01 || Enc_Old == 0x03 && Enc_Now == 0x02) Enc_Ago = Enc_Now;
if(Enc_Old == 0x00 && Enc_Ago == 0x01 && Enc_Now == 0x03 || Enc_Old == 0x03 && Enc_Ago == 0x02 && Enc_Now == 0x00)
{
Enc_Old = Enc_Now;
if(EC11_Type == 1)
{
ScanResult =-1;
}
else
{
if(Enc_IF1 == 0) Enc_IF1=1;
else
{
Enc_IF1=0;
ScanResult =-1;
}
}
}
}
}
还是37楼的这代码牛逼,2次扫描即可以正确检测,而且变量就一个,非常精简,在A和B都在低电平状态时执行处理,果然高手
37#这是以前我写的检测旋转编码器的代码,跟楼主的思想是一样的,
sbit FSA = P3^7; //飞梭右旋
sbit FSB = P3^5; //飞梭左旋
uint8_t fsss=0;//飞梭按钮状态
//检测飞梭
void feisuo_check(void)
{
if(FSA==1 && FSB==1) {//飞梭没有旋转
fsss=0;
return;
} else if(FSA==0 && FSB==1 && fsss==0) {
fsss='R'; //可能是右旋
} else if(FSA==1 && FSB==0 && fsss==0) {
fsss='L'; //可能是左旋
} else if(FSA==0 && FSB==0 && fsss!=0xFF) {
if(fsss=='L') {
//处理左旋
fsss = 0xFF;
} else if(fsss=='R') {
//处理右旋
fsss = 0xFF;
}
}
} |
|