一,什么是EC11编码器

实物图:

封装图:

引脚介绍:

A、B、C:编码器数据引脚,C为公共端,AB为信号端。

D、E:按键引脚,相当于按键开关。

6,7:固定编码器引脚,不接入电路。

二,模块原理

内部原理:(请仔细阅读以下说明,方便您快速了解EC11编码器)

        简单的原理如上图所示,C作为公共端,我们可以根据实际的需求来设置,一般情况下我们都接地,这样方便我们进行代码调试。AB为数据端,AB转动存在相位差,所以通过AB的关系来获取编码器的转向信息,一般来说A在前B在后是正转即顺时针,这里的前后是指电平的变化前后,编码器实际就是一个开关,只是我们使用一个旋转开关同时控制两个输出而已。

        在了解编码器的内部原理之前,我们应该了解一下什么是编码器的档数(或者说定位),正常的EC11编码器有15档、20档等,这里的档可以理解为,我们转动一圈,开关内部闭合与打开多少次,由原理图可知,我们编码器的内部实际上是一个单刀开关,转动一次之后,开关改变一次状态,A与B的电平就发生翻转。

       重点来了,为了区分我们编码器转动的方向,即是正转还是翻转,这跟内部的机械结构有关,一般来说,正转时A相位快于B,反转时A相位慢于B这样我们就可以通过A的跳变沿结合B的电平来确定正转与反转了。相比较于电位器的读取AD值,他的作用在于可以不停的旋转,而且只有发生旋转的时候,AB才会发生改变。

        除此之外,我们还要了解EC11的独立按键作用,我看很多的文章都没提高EC11这个独立按键,其实这个是EC11相比较与其他的按键的精华之处,在于我们通过按键选择模式,然后旋转来确定大小,在实际的应用当中非常广泛,例如我们的热风机调温,就是使用到这个,还有电子手表也在广泛的使用该器件,只是型号不同而已。

在研究EC11的时序之前首先要了解一点,EC11按旋转的输出动作可以分为两种。一种是两定位一脉冲,即转两格A、B对C端输出一个完整脉冲(转一格就只是由低电平->高电平或由高电平->低电平);另一种一定位一脉冲,即就是转一格,A、B对C端输出一个完整脉冲。大多数的编码器都是一定位一脉冲。

如果是一定位一脉冲的类型,不转动的时候A,B于C端都不导通。如果是两定位一脉冲的类型,会有A,B与C端导通和A,B与C端不导通两种情况。稍微转一下转轴然后测量,若A,B与C端都导通,那么就是两定位一脉冲类型。虽然这种EC11无步进手感,但是大多数也是转一圈输出15脉冲(30格)或20脉冲(20格)的类型。

三,电路连接

AB引脚其中一个接入外部中断,另一个接入普通的IO口,C引脚直接接地。

DE引脚其中一个接入普通IO口,另一个接地。

有上拉电阻

初始化的时候,IO不需要要配置内部上拉电阻,即配置普通模式(准双向、双向模式)即可。这个R4、R5、R6非必要,可以不用接入电路。

无上拉电阻

初始化的时候,IO要配置内部上拉电阻,否则无法编码。

四,代码编写

使用STC15单片机为例,将A引脚接到P32,B引脚接到P33,开始外部中断1,选择下降沿触发,使用P32作为中断输入。

基本的时序:

工作流程是:旋转编码器\RightarrowP32口下降沿触发外部中断1\Rightarrow判断P33的极性\Rightarrow确定正反转


unsigned char num; 

void INT0_Init()
{
	IT0=1;    //下降沿触发
	IE0=0;    //清楚中断标志位
	EX0=1;    //打开外部中断请求
	EA=1;     //打开中断总开关
	
}
  
void INTO_Routine() interrupt 0
{
	if(P33) 		//逆时针
	{
		num--;
	}
	else			//顺时针
	{
		num++;
	}		
}

这里的顺时针和逆时针可由自己调试确定,毕竟不同的结构正反也不同。

值得一提的是,P32、P33引脚不是唯一的,只需要将A接入外部中断触发即可,P33则可以换到其他引脚使用。

五,软件消抖

EC11在实际的使用过程中,会存在很多抖动的问题,有时候我们只是转动一格,但是单片机进入了两次中断。如果我们需要更加流畅去操作,即转动一格只进入一次外部中断,这时候需要我们对EC11编码器进行消抖。

消抖方式:硬件消抖、软件消抖。

硬件消抖

一般是采样并联电容的办法,利用电容电压不能突变的性质,对其进行滤波,这里我就不多介绍了,如果感兴趣的话,可以去搜索相关的文章。

软件消抖

一般是使用延时的办法,避开机械抖动的那段时间,从而达到滤波的目的,例如我们的独立按键,就经常使用软件滤波的办法。

消抖思路

①设置定时器中断,定时周期为1ms

②EC11进入一次外部中断,暂时关闭50ms(或者更小,例如20ms),并激活延时变量,使其开始计时。

③计时完成之后,清除中断标志位和延时变量,并重新使能外部中断。


unsigned int ec11_delay;
unsigned char ec11_num; 

void Timer0_Init(void)		//1毫秒@24.000MHz
{
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x30;				//设置定时初始值
	TH0 = 0xF8;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0=1;
	EA=1;
	
}

void INT0_Init()
{
	IT0=1;    //下降沿触发
	IE0=0;    //清楚中断标志位
	EX0=1;    //打开外部中断请求
	EA=1;     //打开中断总开关
	
}


void INTO_Routine() interrupt 0
{
	if(P33) 		//逆时针
	{
		ec11_num--;
	}
	else			//顺时针
	{
		ec11_num++;
	}
    EX0=0;//关闭外部中断
    ec11_delay=1;//激活延时		
}
  

void Timer0_Routinue() interrupt 1 //1ms
{
    if(ec11_delay)
    {
        if(++ec11_delay>=50)  //延时50ms
        {
            IE0=0;              //清楚外部中断标志位        
            EX0=1;              //重新使能外部中断
            ec11_delay=0;       //退出延时
        }
    }
}
    

如果感觉对你有帮助的话,请点个赞吧!

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐