本文介绍用dsPIC30F数字控制器的正交编码器接口(QEI)模块,对电机的速度和位置进行控制的方法。提供了典型电机控制中转子的速度和位置测量的代码实例。
正交编码器接口(QEI)模块
 图1 正交编码器接口信号
 图2 正交编码器接口功能方框图
dsPIC30F的正交编码器接口(QEI)模块提供了一个与增量光编码器的接口,允许从电机或机械系统中,获得速度和相对转子位置信息。QEI模块提供16位时基,接受从增量编码器连接的A、B和标志信号。电机速度和位置信息能用×2或×4分辨率进行测量。 QEI模块有两个速度通道:A相(QEA)和B相(QEB)。两个通道有对应关系,如果A相超前B相,则认为电机的方向是正转或正向的。如果A相滞后B相,则认为电机的方向是反转或反向的。第三个通道是INDX,称标志脉冲通道,电机转子每旋转一周产生一个脉冲,用于确立转子绝对位置的基准。图1是这三个信号的相对时间关系。 由解释A相、B相和标志信号的逻辑译码器和精确计数的上/下计数器组成正交编码器。数字滤波器在输入信号时对信号进行滤波。图2是QEI模块的方框图。这些功能包括: 两相信号和标志信号。 可编程译码器(提供计数器脉冲和计数方向)。 16位上/下位置计数器。 计数方向状态。 ×2和×4分辨率计数。 位置计数器复位的两个模式。 普通用途16位定时器/计数器模式。 QEI或计数器事件产生中断。
应用实例 图3是典型的QEI应用实例,这里交流电机(ACIM)用正交编码器作为反馈信息控制。 应用实例要求: 在0°-360°范围内测量转子角位置。已知增量编码器光栅的数量,设置成相应的定标系数。用一个16位无符号变量表示。 测量角速度。已知的电机最高速度。用一个有符号16位变量表示,这里转子正转时符号是(+),反转时符号是(-)的。 在本例中使用下面的电机和编码器: 电机:Lesson Cat##102684,转子速度3450RPM 编码器:US数字模块E3-500-500-IHT,分辨率500线。
QEI模块初始化
 图3 典型应用方案
 图4 通过滤波器传送的信号,1:1滤波器时钟分频
使能数字滤波器 使能数字滤波器在增量编码器信号中滤波其他信号。对本例所用的结构,图4说明了输入信号的滤波作用。 滤波器计算时,编码器最小脉冲宽度为最高电机速度。在这个实例中,最小脉冲宽度由下式确定:

所配置的滤波器滤出任何小于15祍的脉冲,运行14.75MIPS,能够满足滤波器的要求,滤波器分频器由下式计算:

在QEI模块中有可选择参数,选择64分频,13祍以下的脉冲将被滤出。
增量脉冲计数器 在每个QEn引脚输入增量脉冲计数器信号。为了尽可能提高分辨率,QEI配置成×4。×4计数模式时,每个QEA和QEB信号沿到来时,POSCNT寄存器增量计数或减量计数,图5是×4配置的定时信号。 复位脉冲计数器 脉冲计数器由INDEX引脚复位。图6是INDEX脉冲复位脉冲计数器的定时图。
代码实例 下面是QEI模块初始化的代码实例: 实例1:QEI模块初始化 void InitQEI(viod) { ADPCFG|=0x0038; //配置QEI引脚作为数字输入 QEICONbit.QEIM=0; //禁止QEI模块 QEICONbit.CNTERR=0; //清除计数错误 QEICONbit.QEISIDL=0; //睡眠期间连续工作 QEICONbit.SWPAB=0; //QEA和QEB交换 QEICONbit.PCDOUT=0; //标准I/O引脚工作 QEICONbit.POSRES=1; //标志脉冲复位位置计数器 DELTCONbits.CEID=1; //禁止计数错误中断 DELTCONbits.QEOUT=1; //允许QEn引脚数字滤波器输出 DELTCONbits.QECK=5; //对QEn数字滤波器1:64时钟分频 DELTCONbits.INDOUT=1; // 允许INDEX引脚数字滤波器输出 DELTCONbits.INDCK=5; //对INDEX数字滤波器1:64时钟分频 POSCNT=0; //复位位置计数器 QEICONbit.QEIM=6; //用INDEX位置计数器复位×4模式 Return; }
 表1 变量值和分辨率
用QEI计算角度位置 控制算法采用小数运算,需要将位置计数器结果变换成一个符号小数。下式用于计算每转最大计数值。 MAX_COUNT_PER_REV=PULSES_PER_REV×COUNT_INC_PER_REV-1=500×4-1=1999

这里分辨率为0.18°。 用这个结果,位置计数变量需要将0到1999变换成有符号16位小数值0到32767。下面的公式是定标系数。

标志脉冲配置自动地复位POSCNT。
编码实例 实例2:用QEI计算角位置 int AngPos[2]={0,0}; //用于速度计算的两个变量 int POSCNTcopy=0; { POSCNTcopy=(int)POSCNT; If (POSCNTcopy<0) POSCNTcopy=- POSCNTcopy; AngPos[1]= AngPos[0] AngPos[0]=(unsigned int)(((unsigned long) POSCNTcopy*2048)/125; //0<=POSCNT<=19991到0<=POSCNT<=32752 return; }
 图5 ×4模式正编码器信号
 图6 由标志模式复位
用QEI计算角速度 在一个周期性中断中执行速度计算,因为角速度在一个固定时间周期中是增长的数字,这个中断间隔,必须小于最大转速的1/2转所需时间。电机的转速是3450RPM,所以在这个实例中选用4000RPM,以避免在任何速度计算时溢出。下式用于计算时间间隔:
实例3是定时器1的初始化,用于产生周期性中断,dsPIC DSC运行在14.75MIPS。 实例3:定时器1初始化,产生0.0075秒ISR周期 void InitTMR1(void) { TMR1=0; //复位定时器计数器 T1CONbit.TON=0; //关闭定时器1 T1CONbit.TSIDL=0; //睡眠期间连续工作 T1CONbit.TGATE=0; //禁止进入精确定时器 T1CONbit.TCS=0; //使用Tcy作为时钟源 T1CONbit.TCK=2; //Tcy/64作为输入时钟 PR1=1728 ; //用64预分频器确定中断周期=0.0075秒 IFSobit.T1IF=0; //清定时器1中断标志 IECobits.T1IE=1; //允许定时器1中断 T1CONbits.TON=1; //打开定时器1 turn; } 实例4是在周期性ISR中计算速度变量: 实例4:角速度计算实例 #define MAX_CNT_PER_REV(500*4-1) #define MAXSPEED (unsigned int)(((unsigned long)MAX_CNT_PER_REV*2048)/125) #define HALFMAXSPEED (MAXSPEED>>1) int Speed; void_attribute_((_interrupt_))_T1Interrupt(void) { IFSobits.T1IF=0;//清定时器1中断标志 PositionCalculation(); Speed=AngPos[0]- AngPos[1]; If(Speed>=0) { if (Speed>=(HALFMAXSPEED) Speed=Speed-MAXSPEED; } else { if (Speed<-(HALFMAXSPEED) Speed=Speed+MAXSPEED; } Speed*=2; Return; }
结语 从本文的编码实例,可以得到表1所示数据。 如果测量的速度和角位置需要比较高的分辨率,可以用下列方法: 用比较长地时间周期精确计数。必须避免脉冲计数器寄存器POSCN溢出,所以在这种情况下推荐使用POSCN寄存器的精度。 使用输入捕捉通道代替转换每转计数周期测量。 用每转产生更多脉冲地增量计数器。
代码实例选用dsPIC30F6010 DSC,开发工具是MPLAB IDE7.11和MPLAB C30 v1.31。■ (郭盛利)
|