1. 编码器基础与选型:增量式 vs 式

做电机驱动这些年,我经手过的编码器少说也有十几种。从最简单的增量式光电编码器,到带 SSI 接口的多圈值编码器,每种都有它的脾气。今天咱们先把基础打牢——选错了编码器,后面驱动写得再好也白搭。

1.1 增量式编码器:简单但有个致命缺点

增量式编码器的工作原理,说白了就是数脉冲。码盘上刻着一圈明暗相间的条纹,光通过条纹被接收器检测到,每转过一个条纹就输出一个脉冲。

它只告诉你「动了多少」,不告诉你「现在在哪」。所以每次上电,你都得先回一次零点。我记得有个项目,客户抱怨设备每次开机都要花 10 秒找原点,后来一查,用的就是增量式编码器。

核心输出信号:
  • A 相 / B 相:相位差 90°,用来判断正反转
  • Z 相(零位):每圈一个脉冲,用于回零校准

分辨率怎么算?比如码盘有 1000 线,经过 4 倍频处理,一圈就是 4000 个脉冲。我习惯这么算:分辨率 = 线数 × 4。但要注意,4 倍频是靠 A/B 相的上升沿和下降沿拼出来的,不是编码器本身精度提高了。

避坑: 我曾经遇到过客户把 2500 线的编码器当 10000 线用,结果高速运行时脉冲丢失严重。4 倍频虽然能提高分辨率,但信号质量不好时反而会引入抖动。

1.2 式编码器:上电就知道位置

式编码器就不一样了。码盘上刻的不是条纹,而是一圈圈格雷码。每个位置对应唯一的二进制码,上电就能读出当前角度。

你想想看,这省了多少事?不用回零,不怕掉电丢位置。工业机器人、数控机床这些场合,几乎清一色用值编码器。

特性 增量式 式
上电位置 未知,需回零 立即知道
掉电记忆 无 有(多圈型)
分辨率 取决于线数 + 倍频 取决于位数(如 17 位 = 131072 圈)
抗干扰 脉冲易受干扰 数字信号,抗干扰强
成本 低 高

1.3 分辨率与精度:别搞混了

很多人把分辨率和精度混为一谈。我刚开始做驱动时也犯过这个错。

分辨率是编码器能感知到的最小位移。比如 17 位值编码器,一圈能分 131072 份,分辨率就是 360°/131072 ≈ 0.0027°。

精度是实际位置和测量位置之间的误差。它受码盘加工误差、安装偏心、温度漂移等因素影响。一个 17 位的编码器,精度可能只有 ±0.01°。

我的经验: 选型时先看精度够不够,再看分辨率。分辨率再高,精度跟不上也是白费。比如伺服电机位置环,精度比分辨率更重要。

1.4 ABZ 接口与 SSI 接口

接口协议决定了你怎么读数据。这里重点说两种最常见的。

ABZ 接口(增量式)

A 相和 B 相输出方波,相位差 90°。Z 相每圈一个脉冲。驱动里用定时器捕获上升沿和下降沿,就能算速度和位置。

// 伪代码:ABZ 信号处理
if (A_rising && B_high)   direction = FORWARD;
if (A_rising && B_low)    direction = REVERSE;
position += direction ? +1 : -1;

SSI 接口(式)

SSI 是同步串行接口,用时钟线和数据线传输位置值。主设备发时钟脉冲,编码器在时钟下降沿输出数据位。

我调试 SSI 时踩过一个坑:时钟频率太高,编码器跟不上,数据全是乱的。后来老老实实按手册把时钟降到 500kHz,问题就解决了。

// SSI 读取流程(简化)
for (i = 0; i < BITS; i++) {
    CLK_HIGH;
    delay_ns(100);  // 时钟高电平保持时间
    data |= (MISO << (BITS - 1 - i));
    CLK_LOW;
    delay_ns(100);
}

1.5 选型考量:我一般这么选

选编码器没有万能公式,但有几个原则可以参考:

  1. 看应用场景:普通电机控制,增量式够用;机器人、数控机床,必须值。
  2. 看环境:振动大、油污多的地方,磁编码器比光电编码器靠谱。
  3. 看接口:主控有定时器捕获就用 ABZ,有 SPI 就用 SSI,别硬上。
  4. 看成本:增量式几十块,值几百上千,别杀鸡用牛刀。
我曾经犯过的错: 选了一个 23 位的值编码器,结果主控 SPI 时钟频率太低,读一圈数据要花 2ms,根本跟不上 3000rpm 的转速。后来换了 17 位的,数据读取时间降到 0.5ms,问题解决。

1.6 知识体系总览

下面这张图把本章的核心知识点串起来了。我建议你保存下来,后面写驱动时随时对照。

编码器选型知识体系 编码器 增量式 式 A/B/Z 信号 4 倍频 需回零 SSI 接口 格雷码 掉电记忆 选型考量:场景·环境·接口·成本 分辨率 ≠ 精度 | ABZ 适合低成本场景 | SSI 适合高可靠性场景 | 选型前先算好数据读取时间