4. 编码器与位置反馈:增量式编码器原理、绝对式编码器原理、编码器接口电路设计、位置与速度计算

大家好,我是你们的FPGA与电机控制讲师。今天我们来聊聊伺服驱动里最核心的一环——编码器与位置反馈

说白了,你控制电机转得再准,如果不知道它实际转到哪了,那全是瞎蒙。编码器就是电机的“眼睛”。我这些年调试伺服驱动,至少有一半的坑都出在编码器信号处理上。嗯,咱们今天就把这块彻底讲透。

核心逻辑:编码器将机械位置转换为电信号 → FPGA采集并解码 → 计算位置与速度 → 送给电流环和速度环做闭环控制。

编码器与位置反馈知识体系 增量式编码器 绝对式编码器 接口电路设计 A/B/Z 三相信号 正交解码 · 倍频技术 SSI / BiSS / EnDat 单圈/多圈 · 上电即知位置 差分转单端 · 电平匹配 抗干扰 · 隔离设计 位置计算 + 速度计算 → 闭环控制

4.1 增量式编码器原理

增量式编码器,我习惯叫它“相对位置传感器”。它不告诉你绝对位置,只告诉你“动了多少”。就像你走路数步数,但不知道起点在哪。

工作原理:码盘上刻有均匀的透光/反光条纹。转动时,光耦或磁敏元件输出两路相位差90°的方波——A相和B相。还有一个Z相,每转一圈输出一个脉冲,用来找零点。

我的经验:Z相在伺服驱动里特别重要。上电后第一次找零,必须靠Z相来校准。我曾经遇到过Z相脉冲宽度太窄,FPGA没采到,结果位置一直对不上。后来我在FPGA里加了一个Z相脉冲展宽逻辑,问题就解决了。

正交解码(Quadrature Decoding):

  • A相超前B相90° → 正转
  • B相超前A相90° → 反转
  • 每个边沿触发计数,可实现4倍频(1倍频、2倍频、4倍频)

你想想看,如果编码器是1000线,4倍频后分辨率就是4000脉冲/圈。对于大多数伺服应用,这个精度已经够用了。

FPGA实现正交解码的核心逻辑:

// 伪代码 - 4倍频正交解码
always @(posedge clk) begin
    A_dly <= A;          // 打一拍同步
    B_dly <= B;
    
    // 检测A相上升沿
    if (A && !A_dly) begin
        if (B)  cnt <= cnt - 1;  // 反转
        else    cnt <= cnt + 1;  // 正转
    end
    // 检测A相下降沿
    if (!A && A_dly) begin
        if (B)  cnt <= cnt + 1;
        else    cnt <= cnt - 1;
    end
    // B相类似处理...
end

4.2 绝对式编码器原理

绝对式编码器就高级多了。它每个位置都有唯一的编码值,上电就知道当前角度。不需要找零,不需要回参考点。

两种主流实现方式:

  • 光电式:码盘上有多个同心码道,每个码道对应一位二进制码。常见的有格雷码,相邻位置只变化1位,抗干扰能力强。
  • 磁电式:利用磁阻效应或霍尔效应,输出正余弦模拟信号,通过CORDIC算法解算角度。分辨率可以做到非常高。

通信协议:绝对式编码器通常通过串行总线传输数据。

协议 时钟频率 数据位宽 特点
SSI 1~5 MHz 12~25 bit 简单、点对点
BiSS 1~10 MHz 12~32 bit 双向、速度快
EnDat 1~8 MHz 12~32 bit 海德汉专利、带CRC

注意:绝对式编码器的通信时序非常严格。FPGA做主机时,时钟抖动不能超过纳秒级。我曾经在BiSS协议上吃过亏——时钟线没做阻抗匹配,导致数据采样出错。后来加了RC滤波和终端匹配,通信就稳了。

4.3 编码器接口电路设计

接口电路是编码器和FPGA之间的“桥梁”。设计不好,再好的算法也白搭。

差分信号转单端:

工业编码器大多输出RS-422差分信号(A+、A-、B+、B-、Z+、Z-)。FPGA的IO是单端的,所以需要差分接收器。我常用的芯片是AM26LS32或MC3486。

典型电路连接:

编码器输出         差分接收器          FPGA
A+ ──────────┬─── A+ (输入)
             │
A- ──────────┴─── A- (输入)
                 │
                 └─── R (输出) ──── FPGA IO

注意:接收器输出端要加100Ω上拉电阻,防止浮空。

电平匹配:

  • 5V编码器 → 3.3V FPGA:用电阻分压或电平转换芯片(如SN74LVC4245)
  • 1.8V编码器 → 3.3V FPGA:用升压转换
  • 我个人的习惯是:所有编码器信号进FPGA之前,先过一级施密特触发器(如74HC14),既能整形又能防抖动。

避坑指南:我曾经在一个项目中,编码器线缆长达20米。信号衰减严重,FPGA经常误判边沿。后来我在接收器前端加了共模扼流圈,并在FPGA内部做了数字滤波(连续采样3次一致才认为有效),问题彻底解决。

4.4 位置与速度计算

有了编码器脉冲,怎么算位置和速度?这里有两个关键点:

位置计算:

  • 增量式:累加脉冲计数 × 分辨率 = 机械角度
  • 绝对式:直接读取编码器数据,查表或计算得到角度
  • 注意:增量式要处理溢出问题。我一般用32位有符号计数器,够用了。

速度计算:

速度计算有三种常用方法:

方法 原理 适用场景
M法(测频法) 固定时间内计脉冲数 中高速
T法(测周法) 测量相邻脉冲的时间间隔 低速
M/T法 结合M法和T法 全速范围

FPGA实现M/T法速度计算:

// 伪代码 - M/T法测速
always @(posedge clk) begin
    if (脉冲到达) begin
        pulse_cnt <= pulse_cnt + 1;
        time_cnt  <= time_cnt;      // 锁存时间
    end
    if (定时器溢出) begin
        speed = (pulse_cnt * K) / time_cnt;  // K为标定系数
        pulse_cnt <= 0;
        time_cnt  <= 0;
    end
end

说白了,M法适合高速,T法适合低速。M/T法两者兼顾,但实现复杂一些。我个人在伺服驱动里常用M/T法,因为电机从零速到高速都要控制。

注意:速度计算有延迟。你算出来的速度其实是“上一时刻”的速度。如果速度环带宽很高,这个延迟会导致振荡。我一般会在速度环前加一个一阶低通滤波器,截止频率设为速度环带宽的1/5~1/3。

好了,编码器与位置反馈这块就讲到这里。内容不少,但都是干货。你把这些原理和电路吃透了,后面做伺服驱动就会顺手很多。


公众号:蓝海资料掘金营,微信deep3321