旋转编码器连接单片机

用单片机P1^00 P1^01 两个IO口为AB相输入口 要实现旋转编码器正反转计数,正转累计加数, 反转累计减数 实例如下:请高手指点一二,谢谢!(程序下载编码器正反转都是累计加数。)

while(1)
{
//P1^00=X0 P1^01=X1
if(X0==1 AND X1==1 AND flag0==0 AND flag1==0 AND flag2==0 AND flag3==0 AND flag4==0 AND cc==0)
{
flag0=1;
cc=1;
}
if(X0==0 AND X1==1 AND flag0==1 AND flag1==0 AND flag2==0 AND flag3==0 AND flag4==0 AND cc==1)
{
flag1=1;
cc=2;
}
if(X0==0 AND X1==0 AND flag0==1 AND flag1==1 AND flag2==0 AND flag3==0 AND flag4==0 AND cc==2)
{
flag2=1;
cc=3;
}
if(X0==1 AND X1==0 AND flag0==1 AND flag1==1 AND flag2==1 AND flag3==0 AND flag4==0 AND cc==3)
{
flag3=1;
cc=4;
}
if(X0==1 AND X1==1 AND flag0==1 AND flag1==1 AND flag2==1 AND flag3==1 AND flag4==0 AND cc==4)
{
flag0=0;flag1=0;flag2=0;flag3=0;flag4=0;cc=0;
aa++;
LCD12864_disp2(); //LCD12864液晶动态显示函数
}
}
}

#include < reg52.h> //头文件
sbit anotherbit = P1^2; //旋转编码器另一脚
sbit rotation=P1^0; //旋转编码器中一脚
bit oldbit; //上一状态暂存位
unsigned char led1,led2,led3,led4,ztj;//LED显示缓存,扫描状态机
int xuanzhuanzhi,ctemp;//旋转值
unsigned char code ledseg[17]={0x88,0xBE,0xC4,0x94,0xB2,0x91,0x81,0xBC,0x80,
0x90,0xA0,0x83,0xC9,0x86,0xC1,0xE1,0xf7};
void init(void)
{
TMOD=0x11; //方式1
TR0=1; //启动T0开始扫描数码管
ET0=1; //打开中断
EA=1;
}
void ledscan(void) //数码管扫描程序
{
switch(ztj) //切换状态机
{
case 0: //分支
P2=0xff; //关闭数码管
P0=ledseg[led4];//查表得段码数据
P2=0x7f; //打开数码管
ztj=1; //转移状态
break; //分支结束
case 1:
P2=0xff;
P0=ledseg[led3];
P2=0xbf;
ztj=2;
break;
case 2:
P2=0xff;
P0=ledseg[led2];
P2=0xdf;
ztj=3;
break;
case 3:
P2=0xff;
P0=ledseg[led1];
P2=0xef;
ztj=0;
break;
default: //没有找到分支
ztj=0; //状态机复位
break; //分支结束
}
}
void timer0 (void) interrupt 1 using 1 //T0定时器中断程序,定时时间到,自动运行此程序
{
TH0=(65536-5000)/256; //置定时值,每次时间到都要重新置定时值
TL0=(65536-5000)%256; //每5000us产生一次定时器定时中断(12MHz)
ledscan(); //每5000us扫描一次LED(12MHz)
}
void main(void)
{
init(); //是初始化,打开中断及定时器
while(1)
{
ctemp=xuanzhuanzhi; //复制计数值
if(ctemp<0) //判断符号
{
ctemp=-ctemp; //如果为负数,取反
led4=16; //显示负号
led3=ctemp%1000/100; //提取各位数值
led2=ctemp%100/10; //提取各位数值
led1=ctemp%10; //提取各位数值
}
else
{
led4=ctemp/1000; //提取各位数值
led3=ctemp%1000/100; //提取各位数值
led2=ctemp%100/10; //提取各位数值
led1=ctemp%10; //提取各位数值
}
if(oldbit==1&&rotation==0) //判断前后状态以识别是否发生下降沿
{
if(anotherbit) //判断另一相电平
{
xuanzhuanzhi++; //为高,正转
}
else
{
xuanzhuanzhi--; //为低,反转
}
}
oldbit=rotation; //刷新位暂存值
}
}
温馨提示:内容为网友见解,仅供参考
第1个回答  2019-03-24
欧姆龙的旋转编码器只有5V的有正反转的,其他的24v是只有一个方向的。
第2个回答  2013-10-03
while(1)
{
//P1^00=X0 P1^01=X1
if(X0==1 AND X1==1 AND flag0==0 AND flag1==0 AND flag2==0 AND flag3==0 AND flag4==0 AND cc==0)
{
flag0=1;
cc=1;
}
if(X0==0 AND X1==1 AND flag0==1 AND flag1==0 AND flag2==0 AND flag3==0 AND flag4==0 AND cc==1)
{
flag1=1;
cc=2;
}
if(X0==0 AND X1==0 AND flag0==1 AND flag1==1 AND flag2==0 AND flag3==0 AND flag4==0 AND cc==2)
{
flag2=1;
cc=3;
}
if(X0==1 AND X1==0 AND flag0==1 AND flag1==1 AND flag2==1 AND flag3==0 AND flag4==0 AND cc==3)
{
flag3=1;
cc=4;
}
if(X0==1 AND X1==1 AND flag0==1 AND flag1==1 AND flag2==1 AND flag3==1 AND flag4==0 AND cc==4)
{
flag0=0;flag1=0;flag2=0;flag3=0;flag4=0;cc=0;
aa++;
LCD12864_disp2(); //LCD12864液晶动态显示函数
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(X1==1 AND X0==1 AND flag5==0 AND flag6==0 AND flag7==0 AND flag8==0 AND flag9==0 AND ccd==0)
{
flag0=1;
cc=1;
}
if(X1==0 AND X0==1 AND flag5==1 AND flag6==0 AND flag7==0 AND flag8==0 AND flag9==0 AND ccd==1)
{
flag1=1;
cc=2;
}
if(X1==0 AND X0==0 AND flag5==1 AND flag6==1 AND flag7==0 AND flag8==0 AND flag9==0 AND ccd==2)
{
flag2=1;
cc=3;
}
if(X1==1 AND X0==0 AND flag5==1 AND flag6==1 AND flag7==1 AND flag8==0 AND flag9==0 AND ccd==3)
{
flag3=1;
cc=4;
}
if(X1==1 AND X0==1 AND flag5==1 AND flag6==1 AND flag7==1 AND flag8==1 AND flag9==0 AND ccd==4)
{
flag5=0;flag6=0;flag7=0;flag8=0;flag9=0;ccd=0;
aa--;
LCD12864_disp2(); //LCD12864液晶动态显示函数
}

}
}
//需注意:普通的旋转编码器都是适用于PLC的,也就是输出的是24V的脉冲信号,需要进行电平转换。
//这个程序只是考虑到了AB相时序的变化,没有用到中断处理,可能分辨不出高速信号
//还有变量自己定义吧,应该把所有代码贴出来的,所加的程序仅作参考,没有调试过。追问

  我使用的编码器电压是在DC10v~DC24v,用PC817光藕隔离,谢谢你的实例,我试过,可用,正转累计加数,反转累计减数,只是速度不能太快,太快就会计数不准,我用的编码器分辨率为40的,请指教能否使用外部中断方式计数,外部下降沿中断。

追答

你用的编码器分辨率不高,仅仅是计数的话也没必要用到中断,但是如果要转换成速度信号的话最好使用中断处理,而且建议选用高分辨率的旋转编码器。

本回答被提问者采纳

问下增量式旋转编码器与51单片机的接线问题。
1. 确定单片机的IO口。在51单片机中,有多个IO口可以用来读取旋转编码器的输出信号。需要根据实际情况选择一个合适的IO口。2. 确定IO口的工作模式。在使用IO口时,需要将其设置为输入模式,以便可以读取旋转编码器的输出信号。可以通过单片机的编程软件来设置IO口的工作模式。3. 连接增量式旋转编码器的...

旋转编码器跟51单片机连接如果需要测量出旋转角度应该怎么弄啊,谢谢...
相对型旋转编码器:将A、B路脉冲接入8051(或8031)单片机的脉冲输入端口。用程序读入脉冲的8种状态(即A为高电平;A非为低电平;A↑为A的上跳沿;A↓为A的下跳沿。B 类似),并有8种组合,其中四种组合表示旋转编码器正转,另四种组合表示旋转编码器反转(具体略)。根据旋转编码器每转的编码数...

旋转编码器与单片机怎么连,测角度用
旋转编码器有A、B两个信号线,分别接单片机的两个IO口 A先出现高电平表示正转,反之A是低电平,B出现高电平,编码器是反转

请问旋转编码开关的A、B端接到单片机引脚时,是否还要接上拉电阻?_百度...
1、是否要接上拉电阻,取决于旋转编码器的输出电路结构。2、如果编码器的输出是集电极开路方式的,就必须接上拉电阻。3、如果编码器的输出电路自带上拉电阻,就没哟必要再接了。

推挽输出的光电编码器如何与单片机连接
连接步骤如下:1. 确定编码器的输出信号类型,通常有两种:A\/B相信号和脉冲信号。A\/B相信号是两个正交的方波信号,用于确定旋转方向和位置;脉冲信号是一个方波信号,用于计数旋转次数。2. 根据编码器的输出信号类型选择合适的输入口,通常是单片机的外部中断口或计数器输入口。3. 根据编码器的输出信号...

急问:旋转编码器的信号线与单片机的接法
你的问题大概就是旋转编码器的输出信号电平较高,解决倒也简单,量一下它的高电平是多少,然后用2个电阻分压成0--Vcc就可以了(保险起见还可以再小一点,例如0--0.8Vcc)。另外,最好在分压电阻上再加小电容滤波,然后经施密特触发器(例如7414)整形后再接单片机,这样一来可以减少外部干扰,使...

旋转编码器怎么连接51单片机
旋转编码器 信号主要是两个 都是方波 不过相位差有180度 一个接到外部中断上 另一个接普通IO口 当有外部中断是 中断程序里判断另一个信号是高还是低电平 依据这个判断旋转的方向 还有什么问题 可以HI我

编码器与单片机的连接
可以直接和单片机IO相接,但有的设计者为了降低外部干扰,一般通过D触发器或者光耦后与IO相连,一般的光电编码器都是集电极开路输出型的,你看其说明书有具体电路。一般将A、B相接到定时器输入的IO上,这样比较好处理,将定时器设为计数器模式就可以了。检测步进电机转动角度当然可以做到,这只是基本应用...

编码器的的最小角度是多少,比如是单圈1024的,单片机与编码器具体咋连接...
旋转编码器最小可分辨角度=360\/单圈脉冲个数,比如单圈1024个脉冲时,最小角度=360\/1024=0.352度。最好不要采用编码器直接与单片机相连接的方案,因为这会导致单片机测量负担很重,并且容易丢失计数脉冲导致精度降低。建议你先经过一片HP公司的HCTL-2000译码计数器,再与单片机相连。这样会确保对编码器...

旋转编码器怎么连接51单片机
可以将其A或B脉冲接入到T0\/T1的输入,将定时器设置为计数模式。Z脉冲可以接入到外部中断0或1.

相似回答