4. 编码器与位置反馈:增量式编码器原理、绝对式编码器原理、编码器接口电路设计、位置与速度计算
大家好,我是你们的FPGA与电机控制讲师。今天我们来聊聊伺服驱动里最核心的一环——编码器与位置反馈。
说白了,你控制电机转得再准,如果不知道它实际转到哪了,那全是瞎蒙。编码器就是电机的“眼睛”。我这些年调试伺服驱动,至少有一半的坑都出在编码器信号处理上。嗯,咱们今天就把这块彻底讲透。
核心逻辑:编码器将机械位置转换为电信号 → FPGA采集并解码 → 计算位置与速度 → 送给电流环和速度环做闭环控制。
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