4、相位检测方法:编码器信号处理、霍尔传感器相位检测、旋转变压器解算、无传感器相位估计
相位检测,说白了就是搞清楚电机转子当前转到哪了。这个位置信息有多重要?我打个比方——你开车不知道自己在哪条路上,导航就没法用。同步运动控制也一样,不知道相位,你就没法让电机精准地跟着指令走。
这一章我们聊四种主流的相位检测方法。每种方法我都亲手调过,踩过坑,也总结了一些实用经验。咱们一个一个来。
4.1 编码器信号处理
编码器是工业现场最常见的反馈器件。增量式编码器输出A、B两路正交信号,Z信号用来找零点。绝对值编码器直接输出位置值,上电就能用。
核心处理流程:
- 信号调理:差分信号转单端,滤波去毛刺
- 正交解码:判断A、B相位差,确定旋转方向
- 倍频处理:利用上升沿和下降沿,实现4倍频
- 位置累加:根据方向做加/减计数
关键点:编码器信号最怕抖动和毛刺。我见过一个案例,现场电机低速运行时位置跳变,查了半天发现是编码器线缆屏蔽层没接地。嗯,这种问题往往最隐蔽。
下面是一个简单的正交解码逻辑,用C语言风格写的:
// 正交解码状态机
uint8_t encoder_decode(uint8_t A, uint8_t B) {
static uint8_t last_state = 0;
uint8_t current_state = (A << 1) | B;
uint8_t direction = 0;
// 查表法判断方向
const int8_t table[4][4] = {
{0, 1, -1, 0},
{-1, 0, 0, 1},
{1, 0, 0, -1},
{0, -1, 1, 0}
};
direction = table[last_state][current_state];
last_state = current_state;
return direction; // 1:正转, -1:反转, 0:无变化
}
个人经验:我建议在硬件上做施密特触发整形,软件里再加一级去抖滤波。双重保险,能省掉很多排查时间。
4.2 霍尔传感器相位检测
霍尔传感器成本低、可靠性高,在无刷直流电机(BLDC)里用得特别多。三个霍尔元件间隔120°安装,输出三路高低电平信号。
霍尔信号与转子位置的关系:
| 霍尔编码 (H3,H2,H1) | 转子电角度 (°) | 对应扇区 |
|---|---|---|
| 101 | 0~60 | 1 |
| 100 | 60~120 | 2 |
| 110 | 120~180 | 3 |
| 010 | 180~240 | 4 |
| 011 | 240~300 | 5 |
| 001 | 300~360 | 6 |
霍尔信号每60°电角度变化一次。分辨率确实不高,但胜在简单可靠。我做过一个项目,用霍尔信号做换相触发,配合软件插值,把位置分辨率提高了不少。
注意:霍尔安装位置有偏差时,相位会不准。我曾经遇到过霍尔板装偏了5°,结果电机换相噪声特别大。后来用示波器量霍尔边沿和反电动势过零点,才找到问题。
4.3 旋转变压器解算
旋转变压器(旋变)耐高温、抗振动,在伺服电机和新能源汽车里很常见。它输出两路正余弦信号:
- 激励信号:高频正弦波,通常10kHz左右
- 正弦输出:Vsin = A · sin(θ) · sin(ωt)
- 余弦输出:Vcos = A · cos(θ) · sin(ωt)
解算方法:
- 对Vsin和Vcos做同步解调,提取包络
- 计算反正切:θ = atan2(Vsin, Vcos)
- 做角度跟踪环路(如PLL)消除噪声
我习惯用CORDIC算法做反正切计算,不用查表,精度也够用。下面是一个简化实现:
// CORDIC反正切计算(简化版)
float cordic_atan2(float y, float x) {
float angle = 0.0f;
float x_new, y_new;
if (x < 0) {
x = -x;
y = -y;
angle = PI;
}
for (int i = 0; i < 16; i++) {
float factor = 1.0f / (1 << i);
if (y > 0) {
x_new = x + y * factor;
y_new = y - x * factor;
angle += atan_table[i];
} else {
x_new = x - y * factor;
y_new = y + x * factor;
angle -= atan_table[i];
}
x = x_new;
y = y_new;
}
return angle;
}
避坑指南:旋变的激励信号幅值要稳定。我曾经用了一款便宜的激励芯片,温度一高幅值就漂,导致角度误差越来越大。后来换了专用旋变解码芯片,问题才解决。
4.4 无传感器相位估计
有些场合装不了传感器,或者想降成本,那就得用无传感器方法。说白了,就是通过电机的电气模型来反推转子位置。
常用方法:
- 反电动势法:检测电机端电压,估算过零点。低速时信号弱,效果差
- 磁链观测器:基于电压模型或电流模型,计算磁链矢量角度
- 滑模观测器:利用滑模控制理论,鲁棒性好,但存在抖振
- 扩展卡尔曼滤波:精度高,但计算量大,对MCU要求高
我实际项目里用得最多的是滑模观测器。它结构简单,调好参数后效果不错。不过要注意——滑模的抖振问题,得加低通滤波或者用饱和函数替代符号函数。
核心思路:无传感器方法本质上都是「模型+校正」。模型算出一个大概位置,再用实际测量值去修正。你想想看,这和GPS定位的原理有点像——先估算,再校正。
下面是一个简化的滑模观测器流程:
// 滑模观测器 - 电流误差计算
float sliding_mode_observer(float i_alpha, float i_beta,
float v_alpha, float v_beta) {
// 估算电流
float di_alpha_est = (v_alpha - R*i_alpha - e_alpha_est) / L;
float di_beta_est = (v_beta - R*i_beta - e_beta_est) / L;
// 电流误差
float err_alpha = i_alpha_est - i_alpha;
float err_beta = i_beta_est - i_beta;
// 滑模控制律
e_alpha_est = -K * sign(err_alpha);
e_beta_est = -K * sign(err_beta);
// 从反电动势估算角度
float theta = atan2(-e_alpha_est, e_beta_est);
return theta;
}
注意:无传感器方法在零速和极低速时基本失效。我做过一个项目,要求电机从零速启动带载,最后不得不加了一个霍尔传感器做辅助启动。嗯,有时候纯无传感器方案并不是万能的。
知识体系总览
我把这四种方法的关系画了一张图,方便你理解:
这四种方法各有各的适用场景。编码器精度高但怕振动,霍尔简单但分辨率低,旋变皮实但成本高,无传感器灵活但低速不行。选哪种,得看你的实际工况。
我个人建议:如果条件允许,优先选带传感器的方案。调试周期短,心里也踏实。无传感器方案虽然看起来高大上,但实际调起来坑不少。我当年为了调一个滑模观测器,整整熬了两周才把低速性能稳住。
好了,相位检测方法就聊到这儿。每种方法都有它的脾气,摸透了就好用。
公众号:蓝海资料掘金营,微信deep3321