4、增量式编码器换相:A/B/Z信号解析、正交解码原理、通过UVW信号获取初始位置、换相逻辑与状态机
增量式编码器,说白了就是只告诉你“动了多少”,不告诉你“在哪儿”。但电机控制偏偏需要知道转子在哪儿才能换相。这矛盾怎么解决?
我刚开始做伺服驱动那会儿,也觉得增量式编码器做换相挺麻烦的。后来摸透了A/B/Z和UVW信号的脾气,才发现其实套路很清晰。今天咱们就把这块彻底讲透。
4.1 A/B/Z信号:增量编码器的“三根神经”
增量式编码器最核心的就是三路信号:A相、B相、Z相。我习惯把它们比作编码器的“三根神经”。
- A相和B相:这两路是正交信号,相位差90°。它们负责告诉你位置变了多少、往哪个方向变。
- Z相:也叫零位信号,每转一圈发一个脉冲。它负责告诉你“基准点”在哪儿。
你想想看,如果没有Z相,你只知道电机转了多少步,但不知道当前是第几圈。上电那一刻,你完全不知道转子在哪儿。这就是增量式编码器的“原罪”——没有绝对位置。
核心要点:A/B信号用于计数和判向,Z信号用于归零校准。三者缺一不可。
4.2 正交解码原理:从脉冲到位置的“翻译官”
A相和B相为什么叫“正交”?因为它们的波形相差正好90°电角度。我当年第一次看示波器上的A/B波形时,觉得这东西设计得真巧妙。
正交解码的核心逻辑其实就一句话:通过检测A/B信号的边沿顺序,判断方向;通过计数边沿数量,计算位置。
具体来说,有四种边沿事件:
- A上升沿、B低电平 → 正转一步
- A下降沿、B高电平 → 正转一步
- B上升沿、A高电平 → 正转一步
- B下降沿、A低电平 → 正转一步
反过来就是反转。一个完整的A/B周期,可以产生4个计数脉冲。这就是所谓的4倍频技术。
我的经验:实际项目中,我建议直接用MCU的QEP(正交编码器脉冲)模块,硬件自动解码,省CPU资源。如果非要用GPIO中断去读,记得加滤波,不然一个毛刺就能让位置跑飞。
正交解码的另一个好处是抗干扰。因为A/B两路信号同时跳变的概率极低,所以可以通过“两路同时变化”来判断是否发生了错误。我曾经在一个项目中遇到过编码器线缆被油污浸染的情况,就是靠正交解码的校验机制及时发现并报警的。
4.3 通过UVW信号获取初始位置
增量式编码器本身没有绝对位置,但电机换相需要知道转子在哪儿。怎么办?
答案是:在编码器里额外集成三路霍尔信号——UVW。
UVW信号其实就是三个霍尔传感器,安装在定子上,彼此相差120°电角度。它们输出的是高低电平,组合起来可以表示6个扇区。
| U | V | W | 扇区 | 电角度范围 |
|---|---|---|---|---|
| 1 | 0 | 1 | 1 | 0° ~ 60° |
| 1 | 0 | 0 | 2 | 60° ~ 120° |
| 1 | 1 | 0 | 3 | 120° ~ 180° |
| 0 | 1 | 0 | 4 | 180° ~ 240° |
| 0 | 1 | 1 | 5 | 240° ~ 300° |
| 0 | 0 | 1 | 6 | 300° ~ 360° |
上电时,MCU只需要读取UVW的电平状态,就能知道转子当前在哪个60°扇区内。虽然精度只有60°,但足够让电机启动并正常换相了。
注意:UVW信号只能提供60°的分辨率,不能用于精确位置控制。电机启动后,必须切换到A/B信号的增量计数模式,才能获得高精度位置。
我记得有一次调试,发现电机上电后抖动了一下才转起来。查了半天,原来是UVW信号的上拉电阻没焊,导致电平不稳定。从那以后,我每次画编码器接口电路,都会仔细检查上拉配置。
4.4 换相逻辑与状态机
有了UVW的初始位置,接下来就是换相逻辑了。换相说白了就是:根据转子当前位置,决定给哪两相通电。
对于三相永磁同步电机,标准的六步换相法是这样的:
// 六步换相状态机(电机正转)
// 假设:U+ 表示U相上桥臂导通,V- 表示V相下桥臂导通
状态1 (扇区1): U+ V- W浮空
状态2 (扇区2): U+ W- V浮空
状态3 (扇区3): V+ W- U浮空
状态4 (扇区4): V+ U- W浮空
状态5 (扇区5): W+ U- V浮空
状态6 (扇区6): W+ V- U浮空
每次换相,就是根据UVW信号的变化,切换到下一个状态。我习惯用状态机来实现这个逻辑:
typedef enum {
STEP1, STEP2, STEP3,
STEP4, STEP5, STEP6
} CommutationState;
CommutationState currentState;
void Commutation_Update(uint8_t u, uint8_t v, uint8_t w) {
uint8_t sector = (u << 2) | (v << 1) | w;
switch(sector) {
case 0b101: currentState = STEP1; break;
case 0b100: currentState = STEP2; break;
case 0b110: currentState = STEP3; break;
case 0b010: currentState = STEP4; break;
case 0b011: currentState = STEP5; break;
case 0b001: currentState = STEP6; break;
default: break;
}
ApplyCommutation(currentState);
}
这个状态机看起来简单,但实际项目中坑不少。比如:
- 换相时机:换相太早或太晚,都会导致转矩波动。我一般会在UVW信号跳变后的1~2μs内完成换相。
- 死区时间:上下桥臂切换时,必须插入死区,防止直通短路。我习惯设500ns~1μs,具体看MOS管的关断延迟。
- 状态切换的平滑性:从UVW模式切换到A/B增量模式时,要确保位置计数连续,不能有跳变。
避坑指南:我曾经在一个项目中,因为UVW信号和A/B信号的电气相位没对齐,导致电机在高速时换相错乱。后来我养成了一个习惯:每次换编码器型号,都会先做一次“相位对齐测试”——让电机以极低速转动,同时观察UVW跳变点和A/B信号的Z脉冲是否对齐。
4.5 知识体系总览
为了让你更直观地理解本章的知识结构,我画了一张流程图:
从这张图可以看得很清楚:A/B信号负责高精度位置跟踪,Z信号负责圈数归零,UVW信号负责上电初始定位。三者缺一不可,共同构成了增量式编码器的换相体系。