一般的旋转编码器本身只能提供相对位置信息,不过配合零点信号(即Z相信号)即可确定绝对位置,下面结合TI C2000系列单片机来讨论具体实现方法。
基本原理
在C2000系列单片机中,使用QEQP模块对旋转编码器输入信号进行处理,先根据输入的A、B、Z三相信号生成QCLK内部时钟信号、QDIR方向信号及QI同步信号,这部分工作是由QDU(Quadrature Decoder Unit)子模块完成的。输入信号的极性,输出的来源等均可配置,具体详见数据手册。
生成的QCLK信号来源于A、B两相信号跳变沿,此信号与QDIR方向信号一起确定QPOSCNT寄存器的计数增减,具体时序图如下:
从理论上说,只要确定了一点的绝对位置,就可以通过读取QPOSCNT寄存器获取任意时刻的绝对位置,以两对极电机为例,示例性代码如下:
1  | theta = _IQmpyI32(_IQ(PI / QEP_LINE), EQep1Regs.QPOSCNT);  | 
此处的theta是电角度而不是机械角度,QEP_LINE为编码器线数。对于两对极电机来说,假设QPOSCNT的初值是0,电机完整的顺时针转过一圈后QPOSCNT中的值应该是4 * QEP_LINE,使用上式计算得到的对应电角度就是4PI rad。
再考虑到电机的对称性及角度的周期性,theta的范围在[0, 2PI)内即可,对应的QPOSCNT的范围就是[0, 2 * QEP_LINE)。在C2000单片机中,可以通过QPOSMAX寄存器来设置这个最大值,示例代码如下:
1  | EQep1Regs.QEPCTL.bit.PCRM = 1; // 0 : QPOSCNT reset on an index event  | 
然而,这有两个问题,首先是初始时刻的绝对位置如何确定;其次是如何消除累积误差。解决方法是:初始时刻的绝对位置通过霍尔信号进行估测,累积误差通过Z相同步信号来消除。下面分别来讨论这两个问题。
初始时刻定位
初始时刻的位置确定比较简单,只要预先测定出Ha、Hb、Hc三个霍尔信号输出与绝对角度间的关系,在启动时通过查表的方法即可大致估算出初始角度。因为这一估算过程本来就不要求也不可能精确,故也无需测定霍尔信号跳变沿的准确位置,粗略的使用示波器观察信号估计一下即可。
示例性代码如下:
1  | EQep1Regs.QPOSCNT = GetHall();  | 
这句代码在初始化EQEP模块的时候调用一次,GetHall()函数可返回根据Hall信号猜测出的QPOSCNT寄存器的初值:
1  | // Hall signal delt  | 
Z相同步信号
Z相信号用于对QPOSCNT寄存器进行同步定位,这个信号需要仔细考虑下,否则会造成之后得到的绝对位置存在误差。首先需要考虑的是,Z相信号本身是一个存在一定宽度的脉冲信号,从旋转编码器的原理上来看,正转和反转时Z相信号的上升沿和下降沿对应的绝对位置是不同的,正转时的上升沿对应反转时的下降沿,反之亦然。这就需要在正转和反转时使用不同的边沿触发同步事件,C2000单片机中可以很方便的实现这一功能,只需要设置IEI寄存器即可:
1  | EQep1Regs.QEPCTL.bit.IEI = 3; // 0 : Does nothing  | 
同步事件发生时写入QPOSCNT中的值由QPOSINIT寄存器确定:
1  | EQep1Regs.QPOSINIT = INDEX_OFFSET; // eQEP Position Counter Initialization Value  | 
这里就涉及到INDEX_OFFSET这个值怎么确定的问题,因为Z相脉冲并不是严格的出现于绝对零点位置处,故需要进行角度校正。
角度校正
角度校正的基本思想是,记录下Z相信号对应的绝对角度值,将其写入QPOSINIT寄存器即可,即上述代码中的INDEX_OFFSET宏定义的值。要确定绝对角度,必须要有一个基准,在进行角度校正时,使用预定位的方式确定绝对角度的零点。
具体做法是, 使能三相逆变器,使用SVPWM算法生成一个Ualpha > 0;Ubeta = 0的矢量,Ualpha不宜设置得过大,以免电流过大,此时电机会旋转至绝对零点处。之后使能EQEP模块,将QPOSCNT的值设为0,SEI设为0,以禁用QI信号信号的自动同步复位功能;与此同时,使能IEL,以便在QI信号发生时自动锁存QPOSCNT寄存器的值。以上初始化过程用代码表示如下:
1  | EQep1Regs.QPOSCNT = 0;  | 
按照以上步骤初始化EQEP模块后,禁用三相逆变器,此时电机可以自由旋转。用手旋转电机以产生QI信号,此时QPOSCNT寄存器中的值会被自动锁存在QPOSILAT寄存器中,可以正反多旋转几次电机,记录下若干次QPOSILAT寄存器中的值取平均值即可。读取寄存器的值可以通过使用仿真器进入调试模式实现。
计算得到的平均值即QI信号对应的绝对角度值,将此值定义为INDEX_OFFSET宏写入QPOSINIT寄存器中即可。
注:上述叙述假设编码器Z相信号连接至了
QEPI输入端上,若连接至了QEPS输入端处,只需将QI相关部分改为QS即可,二者的功能基本相同。