1. 算法介绍: 解码程序共处理四种状态,分别是: a.两条线都是高电平时表示编码器无动作,退出. b.先检测测的两条线是01,后检测两条线是10时为正转. c.先检测测的两条线是10,后检测两条线是01时为反转. d.两条线都是低电平时退出,不处理低电平区. (两个状态为一个周期,如正转时,先保存旧值01,然后检测新值为10时就为一个成功检测周期. ) 使用时请先定义好两个IO口 PINA,PINB,和一个周期数cycle,这两个脚可以是任意两个IO脚,cycle 是指编码器旋转多少格(多少周期)动作一次,一般设置为 1 或 2 .该函数返回三个值,返回0时编码器没有动作,返回1时为正转,返回2时为反转,如果在使用时正反转颠倒,可以交换两个IO口的定义. 不管编码器有无动作该函数都会返回一个值!!!!!!!!!! //======================================================================================== #include<reg52.h> typedef unsigned char uchar; sbit PINA = P2^2; //定义IO sbit PINB = P2^3; #define cycle 1 //定义动作周期,编码器旋转多少格有效 #define NULL 0 //定义编码器不动作时的还回值 #define E_RIGHT 0x0e //定义右旋转还回值 #define E_LEFT 0x0f //定义左旋转还回值 uchar WheelNow,WheelOld,RightCount,LeftCount,num; //======================================================================================== uchar WheelRight() { LeftCount=0; RightCount++; if (RightCount>=cycle){ RightCount=0; return(E_RIGHT); } else return(NULL); } //======================================================================================== uchar WheelLeft() { RightCount=0; LeftCount++; if (LeftCount>=cycle){ LeftCount=0; return(E_LEFT); } else return(NULL); } //======================================================================================== uchar EncoderProcess() { uchar keytmp; PINA = 1; PINB = 1; WheelNow=WheelNow<<1; if (PINA==1) WheelNow=WheelNow+1; // 读 PINA WheelNow=WheelNow<<1; if (PINB==1) WheelNow=WheelNow+1; // 读 PINB WheelNow=WheelNow & 0x03; // 将 WheelNow 的 2 - 7 位清零,保留 0- 1 两个位的状态. if (WheelNow==0x00) return(NULL); //当 PINA 和 PINB都为低电平时退出,低电平区不做处理 keytmp=WheelNow; keytmp ^=WheelOld; // 判断新读的数据同旧数据 if (keytmp==0) return(NULL); // 新读的数据同旧数据一样时退出. if (WheelOld==0x01 && WheelNow==0x02){ // 是左旋转否 WheelOld=WheelNow; return(WheelLeft()); //左旋转 } else if (WheelOld==0x02 && WheelNow==0x01){ // 是右旋转否 WheelOld=WheelNow; return(WheelRight()); //右旋转 } WheelOld=WheelNow; // 保存当前值 return(NULL); // 当 PINA 和 PINB 都为高电平时表示编码器没有动作,退出 } //======================================================================================== void inc() { num++; if (num > 99){ num=0; } } // 在此处设置断点看 num 加的变化 //======================================================================================== void dec() { num--; if (num > 99){ num=99; } } // 在此处设置断点看 num 减的变化 //======================================================================================== void main() { while (1){ switch(EncoderProcess()){ case E_RIGHT: inc(); break; case E_LEFT: dec(); break; } } } //======================================================================================== (注:使用定时器每隔1ms读取此函数时,不管编码器转多块也不会丢失num的值) |
欢迎光临 中科因仑“3+1”工程特种兵精英论坛 (http://bbs.enlern.com/) | Powered by Discuz! X3.4 |