了解EC11旋转编码器,编写EC11旋转编码器驱动程序。

时间:2024-03-11 13:25:30

一、EC11旋转编码器基本认识

(1)、ALPS旋转编码器选型垂直型

 

(2)、ALPS旋转编码器选型侧装型

 

(3)、ALPS旋转编码器选型机械尺寸图

(4)、ALPS旋转编码器选型引脚图

 

(5)、ALPS旋转编码器选型内部触点开关结构图

(6)、ALPS旋转编码器选型时序图

 (7)、EC11旋转编码器测试电路原理图接法

  1、接外部上拉电阻,适用于浮空输入和输入上拉模式的IO口,如下图所示。

 

  2、无外部上拉电阻,几乎所有单片机IO口都可以设置为输入上拉模式的IO口,如下图所示。

 

二、EC11旋转编码器初级认识

(1)、EC11旋转编码器按旋转出动作

 EC11旋转编码器按旋转的输出动作分为2种,一种就是转一格,A、B对C端输出一个完整脉冲,简称一定位一脉冲;另一种是转两格,A、B对C端输出一个完整脉冲(转一格就只是由低电平---高电平或由高电平---低电平),简称两定位一脉冲。

(2)、EC11旋转编码器按旋转出动作:一定位一脉冲

  1、一定位一脉冲EC11旋转编码器转动一格输出波形图

 

解释上图:一定位一脉冲的EC11旋转编码器按测试电路图的接法,在静止的时候A、B两线输出都是高电平。转动一格,A、B两线各自输出一个低电平脉冲,然后又回到高电平状态,对应于EC11旋转编码器内部A、B两个触点开关的动作为:断开---闭合---断开。

(3)、EC11旋转编码器按旋转出动作:两定位一脉冲
  1、两定位一脉冲EC11旋转编码器转动一格输出下降沿波形图
 

   2、两定位一脉冲EC11旋转编码器转动一格输出上升沿波形图

 

解释上两图:两定位一脉冲的EC11旋转编码器稍微复杂一些,转动一格只会输出半个脉冲。静止时,A、B触点开关可以是断开的也可以是闭合的。若初始状态时A、B都是高电平,转动一格就输出从高电平到低电平的下降沿,随后一直输出低电平,对应于EC11旋转编码器内部A、B两个触电开关的动作为断开---闭合。若初始状态时A、B都是低电平,转动一格就输出从低电平到高电平的上升沿,随后一直输出低电平,对应于EC11旋转编码器内部AB两个触点开关的动作为闭合---断开。由于两定位一脉冲EC11旋转编码器会有两种初始状态,写驱动程序就需要考虑多一些情况。再者,这类EC11旋转编码器在转动到内部A、B触点一直闭合的时候,就相当于把上拉电阻的另一端接地,无形中加大了系统的功耗(若外接10K上拉电阻到5V电源就是500uA的电流),这对于低功耗应用来说是非常不利的。

(4)、EC11旋转编码器旋转定位和脉冲分辨
目前分有20定位数20脉冲与30定位数15脉冲。咋样分辨20定位数20脉冲与30定位数15脉冲?要辨别的话也很简单,拿一个位未知类型的EC11旋转编码器,看准一个点转一圈,边转圈边数这一圈有多少格就知道了。一般转一圈有30格的都是两定位一脉冲的类型,20格的都是一定位一脉冲的类型。对于没无步进手感的EC11旋转编码器,旋转的时候是均匀的阻尼感,而不会有一格一格的步进手感,这种时候想辨别就需要用一个万用表了。如果是一定位一脉冲的类型,不转动的时候A,B于C端都不导通。如果是两定位一脉冲的类型,会有A,B与C端导通和A,B与C端不导通两种情况。稍微转一下转轴然后测量,若A,B与C端都导通,那么就是两定位一脉冲类型。虽然这种EC11旋转编码器无步进手感,但是大多数也是转一圈输出15脉冲(30格)或20脉冲(20格)的类型。
三、EC11旋转编码器进一步认识
(1)、EC11旋转编码器旋转与按下按键波形图

(2)、EC11旋转编码器一定位一脉冲波形图

  1、EC11旋转编码器正转一定位一脉冲波形图

 解释上图:旋转EC11旋转编码器操作顺序为:正转一格---停顿---连续正转---停

 2、EC11旋转编码器反转一定位一脉冲波形图

 解释上图:旋转EC11旋转编码器操作顺序为:反转一格---停顿---连续反转---停

 (3)、EC11旋转编码器一定位一脉冲波形图解读

根据以上正反转一定位一脉冲波形图可知:若将EC11旋转编码器的A端视为时钟,B端视为数据,整个EC11旋转编码器就可以视为根据时钟脉冲输出信号的同步元件。可以看做数据在时钟的边沿处输出(即时钟线检测边沿,数据线检测电平,这个思路编程最简单),当EC11旋转编码器正转时,在时钟线的下降沿处,数据线为高电平,或在时钟线的上升沿处,数据线为低电平;EC11旋转编码器反转时,在时钟线的下降沿处,数据线为低电平,或在时钟线的上升沿处,数据线为高电平。可以不严谨的简单概括为:在时钟的下降沿处,A、B反相为正转,同相为反转。进一步总结为:EC11旋转编码器每转一格,A、B两线就会各自输出一个完整的脉冲,因此我们可以仅检测时钟线的时钟单边沿(上升沿或者下降沿任选一个做检测),根据时钟线的边沿处,信号线的电平来判断EC11旋转编码器是正转还是反转。为什么这样检测?由于一定位一脉冲的EC11旋转编码器在正常情况下A、B线初始状态都是高电平,所以直接检测时钟线的下降沿更方便。(另一种方法也可以看做数据与时钟的相位关系(即检测数据线和时钟线哪根线的边沿先出现,这个思路编程较为复杂,适合做硬件实现):正转时,A线相位超前于B线相位;反转时,B线相位超前于A线相位。使用简单的数字逻辑电路(异或门与D触发器)就可以识别到A、B的相位关系与转动次数。

 (4)、EC11旋转编码器一定位一脉冲驱动编程

#define EC11_A_Now P36 //EC11旋转编码器的A引脚,视为时钟线,也表示EC11旋转编码器A引脚当前状态,未旋转时处于高电平状态。
#define EC11_B_Now P35 //EC11旋转编码器的B引脚,视为信号线,也表示EC11旋转编码器B引脚当前状态,未旋转时处于高电平状态
#define EC11_Key P37 //EC11旋转编码器的按键 
static char EC11_A_Last = 0; //EC11旋转编码器的A引脚上一次的状态
static char EC11_B_Last = 0; //EC11旋转编码器的B引脚上一次的状态
static char EC11_Type = 1; //定义变量暂存EC11旋转编码器的类型,即 0:一定位对应一脉冲,1:两定位对应一脉冲。
//所谓一定位对应一脉冲,是指EC11旋转编码器每转动一格,A和B都会输出一个完整的方波。两定位对应一脉冲,是指EC11旋转编码器每转动两格,A和B才会输出一个完整的方波,只转动一格只输出A和B的上升沿或下降沿。
  char Encoder_EC11_Scan() //EC11旋转编码器扫描函数, 这里只是部分代码 。
{ //以下储存A、B上一次值的变量声明为静态全局变量,方便对EC11旋转编码器对应的IO口做初始化。 // static char EC11_A_Last = 0; // static char EC11_B_Last = 0; char ScanResult = 0; //返回编码器扫描结果,用于分析EC11编码器的动作,0:无动作,1:正转,-1:反转,2:只按下按键,3:按着按键正转,-3:按着按键反转。 if(EC11_Type == 0) //一定位一脉冲的EC11编码器 { if(EC11_A_Now != EC11_A_Last) //判断EC11旋转编码器A引脚当前状态是否不等于EC11旋转编码器的A引脚上一次的状态EC11旋转编码器A引脚为时钟,EC11旋转编码器B引脚为数据,正转时A、B反相,反转时A、B同相。 { if(EC11_A_Now == 0)//EC11旋转编码器旋转后,判断EC11旋转编码器A引脚当前状态是否处在低电平状态。若处在低电平状态,那么EC11旋转编码器A引脚当前状态由高电平状态变为低电平状态,有下降沿产生。由于只需要采集EC11旋转编码器A引脚的上升沿或下降沿的任意一个状态,再检测EC11旋转编码器B引脚输出电平类型,就可以判断出EC11旋转编码器旋转方向。即当EC11旋转编码器A引脚为下降沿或上升沿,EC11旋转编码器B引脚为高电平(即1)或低电平(即0)时,EC11旋转编码器正转,另之反转。 { if(EC11_B_Now == 1) //EC11旋转编码器旋转后,判断EC11旋转编码器B引脚当前状态是否处在高电平状态 ScanResult = 1; //正转 else ScanResult = -1;//反转 } EC11_A_Last = EC11_A_Now; //更新编码器上一个状态暂存变量 EC11_B_Last = EC11_B_Now; //更新编码器上一个状态暂存变量 } } return ScanResult; //返回值的取值:0:无动作,1:正转,-1:反转。 }

(5)、EC11旋转编码器两定位一脉冲波形图

  1、EC11旋转编码器正转两定位一脉冲波形图

解释上图:旋转EC11旋转编码器操作顺序为:正转第一格---停顿---正转第二格---停顿---连续正转---停

  2、EC11旋转编码器反转两定位一脉冲波形图

解释上图:旋转EC11旋转编码器操作顺序为:反转第一格---停顿---反转第二格---停顿---连续反转---停

  3、EC11旋转编码器正转-反转-正转-正转-反转两定位一脉冲波形图

解释上图:旋转EC11旋转编码器操作顺序为:正转一格---反转一格---正转一格---正转一格---反转一格---停

 (6)、EC11旋转编码器两定位一脉冲波形图解读

 

(7)、EC11旋转编码器两定位一脉冲(检测相位超前或滞后的方式)驱动编程

/*  本程序是对上面char Encoder_EC11_Scan()函数的补充。即else对应的if为if(EC11_Type == 0) 即此处EC11_Type!= 0  */                            
else//两定位一脉冲的EC11旋转编码器
{
if(EC11_A_Now !=EC11_A_Last)//判断EC11旋转编码器A引脚当前状态是否不等于EC11旋转编码器的A引脚上一次的状态。若A 0->1 时,B 1->0 正转;若A 1->0 时,B 0->1 正转;若A 0->1 时,B 0->1 反转;若A 1->0 时,B 1->0 反转。 { if(EC11_A_Now == 1)//EC11旋转编码器旋转后,判断EC11旋转编码器A引脚当前状态是否处在高电平状态。 { if((EC11_B_Last == 1)&&(EC11_B_Now == 0))//EC11旋转编码器B引脚上一次状态为高电平,EC11旋转编码器B引脚当前状态低电平状态。 ScanResult = 1;//正转 if((EC11_B_Last == 0)&&(EC11_B_Now == 1))//EC11旋转编码器B引脚上一次状态为低电平,EC11旋转编码器B引脚当前状态高电平状态。 ScanResult = -1;//反转 //下面为正转一次再反转或反转一次再正转处理
if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 0))//EC11旋转编码器A引脚上升沿时,采集的B不变且为0。 ScanResult = 1;//正转 if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 1)) //EC11旋转编码器A引脚上升沿时,采集的B不变且为1。 ScanResult = -1;//反转 } else//EC11旋转编码器旋转后,判断EC11旋转编码器A引脚当前状态是否处在低电平状态。 { if((EC11_B_Last == 1)&&(EC11_B_Now == 0))//EC11旋转编码器B引脚上一次状态为高电平,EC11旋转编码器B引脚当前状态低电平状态。 ScanResult = -1;//反转 if((EC11_B_Last == 0)&&(EC11_B_Now == 1))//EC11旋转编码器B引脚上一次状态为低电平,EC11旋转编码器B引脚当前状态高电平状态。 ScanResult = 1;//正转 //下面为正转一次再反转或反转一次再正转处理
if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 0))//EC11旋转编码器A引脚上升沿时,采集的B不变且为0。 ScanResult = -1;//反转 if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 1))//EC11旋转编码器A引脚上升沿时,采集的B不变且为1。 ScanResult = 1;//正转 } EC11_A_Last = EC11_A_Now;//更新编码器上一个状态暂存变量 EC11_B_Last = EC11_B_Now;//更新编码器上一个状态暂存变量 return ScanResult;//返回值的取值,0:无动作,1:正转;-1:反转。 } }