一般的旋转编码器本身只能提供相对位置信息,不过配合零点信号(即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
即可,二者的功能基本相同。