dsPIC30F 编码器接口怎么配:QEI 4 倍频、索引复位与 4 级捕捉 FIFO 一次讲透

伺服轴回零后位置总差几个脉冲,换编码器也没用。本文按 dsPIC30F 参考手册拆解 QEI 的 x2/x4 倍频、MAXCNT 与索引复位、CNTERR 查错,以及数字滤波分频和 4 级捕捉 FIFO 的取舍。

2026-11-01
dsPIC30FQEI正交编码器输入捕捉数字滤波电机控制

一台包装机的伺服轴,回零后连续跑 200 个循环,累计位置总会差三五个脉冲,换了编码器和线束都没解决。结论先给:编码器本身没坏,问题出在 QEI 的配置上——倍频选错、索引复位的状态没锁住、数字滤波分频把高速边沿吃掉,这三件事任意一件出问题,计数都会慢慢偏。

本文按 Microchip《dsPIC30F 系列参考手册》(DS70060C_CN)第 13 章输入捕捉与第 16 章正交编码器接口(QEI)整理,寄存器定义、模式编码与实例数值均取自该手册。

一、QEI 替你做的事:解码、计数、判方向

增量式编码器输出三路信号:A 相、B 相和每转一次的索引脉冲。A 超前 B 记为正向,B 超前 A 记为反向,两路信号组合出四种状态,走完四种状态算一个正交周期。QEI 模块把这四路状态翻译成"加一"或"减一"的计数脉冲,再送到 16 位位置计数器 POSCNT,同时给出方向状态 UPDN。

模式由 QEICON 的 QEIM<2:0> 选择,这张表值得贴在工位上,配置错一位就是"能计数但不准":

QEIM<2:0>含义位置计数器复位方式每转计数
111QEI 使能,x4 倍频与 MAXCNT 匹配4N
110QEI 使能,x4 倍频索引脉冲(POSRES=1)4N
101QEI 使能,x2 倍频与 MAXCNT 匹配2N
100QEI 使能,x2 倍频索引脉冲(POSRES=1)2N
001QEI 关闭,作 16 位定时器与 MAXCNT 周期匹配—
000/010/011模块关闭或未使用——

注意 x4 与 x2 的差别不在分辨率,而在计数时钟:x4 对 A、B 两相的上升沿和下降沿都计数;x2 只数 A 相的两个边沿,B 相仅用来判方向。同一只 4096 线编码器,x4 每转 16384 个计数,x2 只有 8192 个。

二、x2 还是 x4:先把计数率和 16 位边界算清

倍频选高的代价是计数率成倍上涨。手册给的上限很明确:正交频率最高为 FCY/3,FCY=30 MHz 时 A、B 两相最高 10 MHz。手册里的两个算例可以直接套:6000 RPM 配 4096 线编码器,计数率为 (6000/60)×(4096×4)=1.6384 MHz;10000 RPM 配 8192 线,则是 (10000/60)×(8192×4)=5.46 MHz,已经接近上限的一半。

工况x4 计数率x2 计数率16 位计数器可覆盖圈数
4096 线,3000 RPM(3000/60)×4096×4 = 819.2 kHz409.6 kHz65536÷16384 = 4 圈
8192 线,3000 RPM1.6384 MHz819.2 kHz65536÷32768 = 2 圈

第二列的数字说明一件事:16 位 POSCNT 在 x4 模式下只能撑几圈,超过就必须靠 MAXCNT 或者软件高位扩展。手册给出的取值规则是 MAXCNT = 4N−1(x4)或 2N−1(x2),N 为编码器每转线数;4096 线对应 0x3FFF,写 16384 就是典型错法,计数器会在 0 到 16383 之间少算一个点。

三、复位方式决定"零点":MAXCNT 还是索引

QEIM0=1 时用 MAXCNT 复位。正向旋转时 POSCNT 与 MAXCNT 相等,下一个递增沿把 POSCNT 清 0;反向旋转减到 0 时,下一个递减沿把 MAXCNT 装入 POSCNT,两个方向都会产生一次中断。这种模式适合行程有限的设备,比如丝杆工作台,用 0xFFFF 作 MAXCNT 就等价于"只借中断做高位扩展"。

QEIM0=0 时用索引脉冲复位,前提是 POSRES 位为 1:正向遇到索引脉冲清 0,反向遇到索引脉冲装入 MAXCNT。如果 POSRES=0,计数器不会因索引复位,只会在计满或下溢时翻转,但索引事件依然产生中断——很多"回零后位置差一截"的问题就出在这里,代码以为索引在复位,其实只拿到了一个中断。

索引脉冲的宽度各厂不一致:整周期或半周期的叫非门控,四分之一周期的叫门控。手册的处理办法是"锁存第一次":QEI 在第一个索引脉冲到来时记下当时所处的正交状态转换,之后正转反转都用同一个转换点复位,保证两个方向的零点重合。带 IMV<1:0> 的器件可以手动指定匹配状态,没有该位的器件自动选取。

四、CNTERR:把"丢步"变成能查的错误

索引复位模式下,QEI 还会做边界自检:向上计数时把 POSCNT 与 MAXCNT+1 比较,向下计数时与 0xFFFF 比较,命中就置位 CNTERR(QEICON<15>),并按 CEID(DFLTCON<8>,默认 0 使能)决定是否产生中断。手册的例子很直观:100 线编码器 x4 模式,计数器应走 0~399(0x018E),一旦出现 0xFFFF 或 0x0190,就说明中间丢了边沿或者线序接反。

CNTERR 一旦置位会一直保持,后续同类事件不再重复中断,必须由软件清零。所以它适合做成上电自检和回零校验:回零完成后清一次,跑一段再看有没有再置位,比事后量波形快得多。

五、数字滤波器:挡毛刺,也会挡真边沿

QEA/QEB/INDX 输入都带可编程数字滤波器,规则是"连续三个滤波周期采到同一电平才允许输出变化"。滤波时钟由 FCY 分频得到,QECK<2:0> 与 INDCK<2:0> 提供 1:1 到 1:256 八档。分频越大抗干扰越好,但延时也越大:FCY=30 MHz 时,1:1 的一个滤波周期约 33 ns,三个周期 0.1 µs;1:256 的一个周期约 8.5 µs,三个周期就是 25.6 µs。

QECK 分频滤波时钟周期(FCY=30 MHz)三周期延时适用场合
1:133 ns约 0.1 µs高速编码器,线缆短
1:4133 ns约 0.4 µs机内走线,常规伺服
1:642.13 µs约 6.4 µs长线、变频器旁
1:2568.53 µs约 25.6 µs低速轴、强干扰现场

选档的硬约束是:三个滤波周期的总延时要明显小于编码器最小半周期。819.2 kHz 的计数率对应半周期约 0.61 µs,这时只能停在 1:1 或 1:4,用 1:256 会把正常边沿一起滤掉,表现就是"低速正常、一提速就丢步"。另外 DFLTCON 的位定义在不同型号上有差异:dsPIC30F6010 把索引通道单独做成 INDOUT/INDCK,其他器件用 QEOUT/QECK 统一控制三路,移植代码时要按器件手册核对。

六、输入捕捉:单路脉冲用 IC 更合适

只有一路脉冲的场合——霍尔测速、流量计、单相编码器——用输入捕捉比占用 QEI 划算。ICM<2:0> 支持下降沿、上升沿、每 4 个上升沿、每 16 个上升沿、双边沿五种捕捉,另有 111 的"仅中断"模式。捕获值进入 4 级 FIFO,ICBNE 表示缓冲非空,ICOV 表示溢出:缓冲满 4 个后第 5 个事件到来时,ICOV 置位、第 5 个值被丢弃,而且之后的事件都不再改写缓冲,必须连续读 4 次才能恢复。

中断频率由 ICI<1:0> 控制,可选择每 1~4 次捕捉事件中断一次;双边沿模式例外,每个边沿都产生中断,且不置 ICOV。还有一个容易被忽略的时序细节:时基每个 TCY 加 1 时,捕捉到的值可能比真实边沿晚 1~2 个指令周期,把时基预分频后这个偏差就被消除。切换捕捉模式时预分频计数器不会清零,手册建议先把 ICM 写 000 关闭模块,再写新模式,否则第一次捕捉可能提前触发。

低功耗场景要特别注意:休眠时捕捉模块只能当外部中断用,必须配成 ICM=111,其他模式下的边沿不会唤醒器件。UART 自动波特率也借用捕捉通道,此时必须工作在双边沿模式,由 RX 引脚内部接入,外部捕捉引脚被断开。

七、七步落地与排查表

  1. 数编码器线数 N,按需要的分辨率选 x4 或 x2,别默认用 x4。
  2. 算最高计数率 (RPM/60)×N×倍频,控制在 FCY/3 以内并留三成余量。
  3. 定零点方案:行程固定用 MAXCNT=4N−1 或 2N−1,每转回零用索引并置 POSRES=1。
  4. 按最小半周期选 QECK/INDCK,三周期延时要明显小于半周期。
  5. 打开 CNTERR 中断,回零后清标志,运行中定期复查。
  6. POSCNT 一律按字访问,字节读取可能在计数中被拆开。
  7. 单路测速改用输入捕捉,切模式前先写 ICM=000。
/* dsPIC30F QEI 初始化:4096 线编码器,x4 倍频,MAXCNT 复位 */
#define ENC_LINES    4096
#define ENC_MAXCNT   (4 * ENC_LINES - 1)     /* 16383 = 0x3FFF,不是 16384 */

void QEI_Init(void)
{
    QEICON = 0x0000;                 /* 先关模块,避免切换时误计数 */
    DFLTCONbits.QEOUT = 1;           /* 使能 QEA/QEB/INDX 数字滤波 */
    DFLTCONbits.QECK  = 2;           /* 滤波时钟 1:4,三周期约 0.4 µs */
    MAXCNT = ENC_MAXCNT;
    POSCNT = 0;                      /* 按字写入,不要用字节访问 */
    QEICONbits.POSRES  = 0;          /* MAXCNT 复位模式下该位无效 */
    QEICONbits.QEISIDL = 0;          /* 空闲模式继续计数 */
    QEICONbits.QEIM    = 7;          /* x4 倍频,MAXCNT 匹配复位 */
    IFS2bits.QEIIF = 0;
    IEC2bits.QEIIE = 1;              /* 计满/下溢中断 */
}
现象常见根因改法
回零后每圈都差固定几个计数MAXCNT 写成 4N 而不是 4N−1按 4N−1 或 2N−1 重写周期值
正转反转的回零点不重合索引复位状态未锁存,或 IMV 配错检查 POSRES,按索引脉宽核对 IMV
低速正常,一提速就丢步滤波分频过大,吃掉真实边沿把 QECK 降到 1:1 或 1:4
位置值偶尔跳一大截字节方式读 POSCNT,高低字节不同步统一按字读取,或读两次比对
回零动作做了,位置却没清只开了索引中断,POSRES=0置 POSRES=1,或改用 MAXCNT 复位
休眠后编码器事件唤不醒捕捉模式不是 ICM=111唤醒前切换为仅中断模式

一句话总结:QEI 的所有"计数不准",几乎都能归到三笔账上——倍频与计数率、复位方式与零点、滤波与边沿宽度。把 MAXCNT 写成 4N−1、把 POSRES 打开、把滤波延时压到半周期以下,编码器就不需要靠换件来解决丢步。

还想接着看:dsPIC30F2010 的 MCPWM 死区、FLTA 保护与 ADC 同步采样、dsPIC33FJ16MC102 电流环的 Q15 定点化与饱和回写、STM32 TIM1 与编码器接口的关节 FOC 配置。

本文基于 Microchip《dsPIC30F 系列参考手册》(DS70060C_CN)第 13 章、第 16 章技术资料整理优化。

需要定制开发?

沧州艾诺威电子 — 国家高新技术企业,20+项国家专利
嵌入式系统开发 · 物联网方案 · AI智能硬件 · 一站式交付

立即微信咨询

电话:13930711029 | 邮箱:tech@czinv.com | 24小时内响应