3、开环对齐法(霍尔传感器)
开环对齐法,说白了就是给电机通一个固定方向的直流电,让转子自己转到某个位置。然后我们读一下霍尔的状态,就知道这个状态对应哪个电角度了。
这个方法我用了很多年。简单、粗暴、有效。尤其适合刚焊好板子、还没写过复杂算法的阶段。
3.1 原理讲解
先想一个问题:霍尔传感器装在哪里?
通常装在定子上,三个霍尔相隔 120° 电角度。转子转动时,霍尔输出 000 到 111 的六种状态(有些组合可能不出现)。
但问题是——霍尔状态和电角度的对应关系,取决于你装霍尔时的机械位置。装偏一度,整个映射就偏一度。
开环对齐法的核心思路就一句话:
给电机施加一个已知方向的电压矢量,让转子锁定到该矢量对应的电角度,然后记录此时的霍尔状态。
举个例子。我施加一个指向 0° 电角度的电压矢量(比如 A 相正、B 相负、C 相悬空),转子就会转到 0° 附近。这时候读霍尔,假设读到 101。那么我就知道:霍尔状态 101 对应电角度 0°。
重复六次,就能把六个扇区的映射全部标定出来。
我的经验: 第一次做这个实验时,我犯了个低级错误——没给电机加足够的电流。结果转子根本没锁住,轻轻一碰就跑了。后来我习惯把电流设到额定值的 30%~50%,保证锁定力矩足够。
3.2 操作步骤
下面是我在实际项目中总结的步骤。每一步都踩过坑,你照着做基本不会翻车。
- 准备工作
- 电机空载,最好把负载脱开
- 确认驱动板供电正常,电流限制打开
- 准备好示波器或串口,用来观察霍尔状态
- 施加第一个电压矢量
- 比如:A 相输出 PWM 正,B 相输出 PWM 负,C 相高阻
- 这个矢量对应电角度 0°
- 保持 1~2 秒,让转子稳定
- 读取霍尔状态
- 用 GPIO 读取三个霍尔引脚的电平
- 记录为 3 位二进制数,比如 101
- 存入表格:霍尔状态 101 → 电角度 0°
- 切换到下一个矢量
- 按 60° 步进,依次施加 60°、120°、180°、240°、300° 的电压矢量
- 每次等待转子稳定后,记录对应的霍尔状态
- 验证完整性
- 检查是否覆盖了所有出现的霍尔状态
- 正常应该有 6 个不同的状态
注意: 有些电机在施加电压矢量时,转子可能卡在相邻两个扇区的边界。这时候霍尔状态会抖动。我建议多读几次,取稳定值。如果一直抖动,说明电流太小,加大电流再试。
3.3 代码实现(C语言)
下面是我常用的标定代码。结构很简单,但很实用。
// 霍尔状态到电角度的映射表
// 初始化为无效值 0xFF
uint8_t hall_to_angle[8] = {0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF};
// 电压矢量表:每个矢量对应一个电角度
// 这里用简单的开关组合示意
typedef struct {
uint8_t a_on; // A相上管
uint8_t a_off; // A相下管
uint8_t b_on;
uint8_t b_off;
uint8_t c_on;
uint8_t c_off;
} voltage_vector_t;
voltage_vector_t vectors[6] = {
// 0°: A+, B-, C悬空
{1, 0, 0, 1, 0, 0},
// 60°: A+, C-, B悬空
{1, 0, 0, 0, 0, 1},
// 120°: B+, C-, A悬空
{0, 0, 1, 0, 0, 1},
// 180°: B+, A-, C悬空
{0, 1, 1, 0, 0, 0},
// 240°: C+, A-, B悬空
{0, 1, 0, 0, 1, 0},
// 300°: C+, B-, A悬空
{0, 0, 0, 1, 1, 0}
};
void calibrate_hall_offset(void) {
uint8_t hall_state;
uint8_t angle_index;
for (angle_index = 0; angle_index < 6; angle_index++) {
// 施加电压矢量
apply_voltage_vector(&vectors[angle_index]);
// 等待转子稳定(建议 500ms~1000ms)
delay_ms(800);
// 读取霍尔状态
hall_state = read_hall_state();
// 存入映射表
// 电角度 = angle_index * 60
hall_to_angle[hall_state] = angle_index * 60;
// 打印调试信息
printf("Vector %d°: Hall = 0x%02X\n",
angle_index * 60, hall_state);
}
// 关闭所有输出
disable_all_outputs();
}
我的习惯: 标定完成后,我会把 hall_to_angle 数组保存到 EEPROM 或 Flash 里。下次上电直接读取,不用重新标定。除非你拆过霍尔,否则这个映射不会变。
3.4 验证方法
标定完了,怎么知道对不对?我一般做三个验证。
验证一:手动旋转
用手慢慢转动电机转子。同时通过串口打印当前的霍尔状态和对应的电角度。正常情况应该是:
- 霍尔状态按顺序循环变化(比如 101 → 100 → 110 → 010 → 011 → 001 → 101)
- 电角度也按 60° 步进递增或递减
- 没有跳变或重复
验证二:闭环运行
用标定好的映射表跑一个简单的速度环。如果电机能平稳运行,没有明显的顿挫感或异响,说明标定基本正确。
我曾经遇到一个问题: 标定完跑起来,电机在某个位置总是卡一下。查了半天,发现是有一个霍尔状态没被标定到——那个状态在标定时因为转子抖动被漏掉了。后来我加了多次读取取众数的逻辑,才彻底解决。
验证三:反向验证
用已知的霍尔状态反推电角度,然后手动给一个对应的电压矢量,看转子是否指向预期的方向。这个比较费时间,但最可靠。
3.5 核心流程总结
下面这张图把整个开环对齐法的流程串起来了。你可以把它贴在工位上。
嗯,开环对齐法就这些内容。它不复杂,但很基础。你把这个方法吃透了,后面讲闭环校准、在线校准的时候,理解起来会轻松很多。