利用EQEP实现编码器的位置与转速测量

零 前言

研究了这么久的电机控制,DSP28335的EQEP模块实际上了解的并不是特别多,因为之前做实验都是用的师兄整的代码。所以这回我觉得好好研究一下这玩意,正好我手上现在有一种光电式的,还有一种磁编码器,一起整理一下。然后实现了一下相关的代码,完成了转速和位置的测量。

“生活可真是艰难呢”

一 光电编码器
1 E6C2CWZ6C型光电编码器

E6C2-CWZ6C输出引脚包含A、B、Z三相,以及5-24V电源与地,输出状态为NPN集电极开路输出,对应实物照片及输出回路如下:

当三极管导通时,集电极输出低电平;当三级管关断时,集电极输出悬空。因此,该编码器在工作时,需要外部添加上拉电阻,如下图所示。因此,这边我额外在在编码器输入信号线上增加了上拉电阻。

当然也可以采用光耦隔离的方式,如下图所示。这边我的另外一个控制板采用的是这种光耦隔离的方案,本文中暂不涉及。

此时,输出信号定义如下,注意动作图中的ON、OFF晶体管开通或关断状态:

光电编码器我见过的应用主要是在感应电机的控制过程中,只要三根线就够了。其他的常见编码器引脚信号还有:A、B、Z信号的反相信号,这个是为了消除共模噪声干扰的;U、V、W信号(120度相位差),这个用在BLDC控制上的,和霍尔位置传感器类似,可参考[1]这里不做详述;或者只有计数时钟和方向信号的,这个28335是有对应的控制方式的。

2 硬件连接

输入信号与地并联噪声滤除电容,然后经过两次反相器,一方面是增强信号能力,另外编码器供电采用5V,这个SN74LVC14供电是个3.3V,还起到电平转换的效果。后面直接连接入DSP接口即可。

二 磁传感编码器
1 MT6825磁编码器

目前常见的小型伺服永磁电机,经过拆解可以发现,其使用的主要是磁角位置编码器,使用的我这边看到使用的芯片型号为MagnTek的MT6825磁编码芯片,再配上一些差分芯片及控制芯片,其输出引脚包含了正反的A、B、Z以及U、V、W信号。按照我早年做机器人的经验,这种编码器在转动处没有直接的机械连接,因此在具有较强机械振动的应用场合,比滑动电阻式以及光电编码器更有优势。根据数据手册,磁铁与芯片之间的间隙最好不要超过3mm。下面的是示意图和实物照片。

下图给出了A与反向A信号的波形,以及A与B信号的波形。

2 硬件连接

由于采用差分的输出方式,所以通常需要经过滤波,然后接差分转单端芯片,比如IT的AM26C32,这个用了很多年了,以及后接反相器做电平转换(如上部分所述)。

三 基于28335 EQEP单元实现位置与转速测量
1 我的编码器到底有多少线以及位置的确定

位置计数与控制单元(Position Counter and Control Unit, PCCU)通过QEPCTL和QPOSCTL寄存器,来实现编码器的计数设置。其中的一个运行模式是,位置计数器可以在Index事件时清零(正转)或者置为设定最大值QPOSMAX(反转)。因为我记得我这个编码器大概有2500线,这样我就可以测试一下是不是这样。具体的寄存器定义,只要把[4]这个文档整明白了,问题不大。中文翻译可以看[5]。

设置代码,让他在Z信号时刻清零位置计数器

EQep1Regs.QEPCTL.bit.PCRM=00;

可以得到如下结果

果然,大概在10000的位置,位置计数器清零,所以我的编码器确实是2500线。另外在这个模式下,每一圈的z信号都会让他清零。

与此同时,采用这个模式还可以实现旋转位置的测量,只要将QPOSMAX设置为最大位置脉冲数减一即可,我这里是9999。这样,不管他怎么转,都是在0到9999这个范围里。

2 等时间长度采样法(也称M法)实现转速计算

计算公式如下

这种方法一般书里都描述对应于低速并不合适,也就是说如果编码器线数较低,他可能在一个采样周期转不过两根线。例如,考虑一个2500线的编码器,那么编码器转一周在28335内部经过四倍可以得到10000个脉冲,也就是一个脉冲间隔对应0.0001个圆周。这时候,如果用100Hz的等时间采样来计及编码器的计数,那么理论上最低速度是0.0001*100=0.01rps,即0.6rpm。我觉得这种分辨率对我来说已经足够了(200rpm左右),所以我就用这个方法就好了。

这边我再多描述一些,在eqep模块里,他有一个计数器模块,这个可以用来实现等时间的脉冲计数采样,也就是M法。另外,他还有一个捕捉模块,这个模块可以用来实现几个固定脉冲位置之间的时间采集,也就是T法。这里只用定时实现计数就完了。

28335的EQEP里面配有一个Unit Timer Base,他是一个SYSCLKOUT驱动的32bit计时器,并且还带有中断功能。当timer的计数器QUTMR等于设置的周期值QUPRD时,单位时间中断出现(QFLG[UTO]置位)。与此同时,设置周期值QUPRD恰好为单周总脉冲-1,

以下是基于DSP28335的EQEP模块测量增量式编码器速度的示例代码: ```c #include "DSP2833x_Device.h" #include "DSP2833x_Examples.h" void InitEQEP(void); volatile struct EQEP_REGS *EQep1Regs; Uint32 Position; Uint32 PrePosition; float Speed; void main(void) { InitSysCtrl(); InitPieCtrl(); InitPieVectTable(); InitEQEP(); EINT; while(1) { // 计算速度 Position = EQep1Regs->QPOSCNT; Speed = (float)(Position - PrePosition) / 400000 * 100000000; // 400000为编码器线数,100000000为时钟频率 PrePosition = Position; DELAY_US(1000); } } void InitEQEP(void) { EQep1Regs = &EQEP1_REGS; // 初始化EQEP模块 EQep1Regs->QDECCTL.bit.QSRC = 0; // 使用A、B相 EQep1Regs->QDECCTL.bit.XCR = 1; // 2倍计数 EQep1Regs->QDECCTL.bit.SPSEL = 1; // 时钟频率为SYSCLKOUT/2 EQep1Regs->QDECCTL.bit.SOEN = 3; // 使能正向和负向计数器 EQep1Regs->QPOSCTL.bit.PCSHDW = 1; // PCSHRD复位时,将PCSHDW更新到POS EQep1Regs->QPOSCTL.bit.PCLOAD = 1; // PCSHRD发生计数器复位,POS计数器将被重新加载 EQep1Regs->QPOSCTL.bit.PCPOL = 1; // PCSHRD极性为正 EQep1Regs->QPOSCTL.bit.PCE = 1; // 使能位置计数器 EQep1Regs->QEINT.bit.PCU = 1; // 使能PCU中断 EQep1Regs->QCAPCTL.bit.UPPS = 0; // 1倍计数 EQep1Regs->QCAPCTL.bit.CCPS = 7; // 128倍预分频 EQep1Regs->QCAPCTL.bit.CEN = 1; // 使能捕获单元 } ``` 在该示例代码中,我们通过 `InitEQEP` 函数初始化了EQEP模块,并且在主循环中使用了 EQep1Regs->QPOSCNT 计算了当前的位置值,然后通过计算上一次位置值和当前位置值之间的差值来计算编码器的速度。其中,编码器的线数为400000,时钟频率为100MHz,因此计算公式为 `(Position - PrePosition) / 400000 * 100000000`。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

obotisr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值