1. 基于反电动势过零检测的方波无感控制启动策略
任务目标
实现永磁同步电机(PMSM)在无位置传感器条件下的方波无感控制启动:通过六步换相法开环强拖电机至可观反电动势转速,检测反电动势过零信号完成换相,待转速稳定后切换至闭环运行,并验证启动可靠性。
核心原理与实现方案
启动过程分三个阶段:定位(给定固定矢量使转子对齐)、开环强拖(按设定换相频率递增驱动)、闭环切换(反电动势过零检测有效后切入)。反电动势过零检测采用端电压比较法:悬空相端电压与中性点电压比较,过零时刻滞后换相点30°电角度,需软件延时补偿。
关键完整代码
// 方波无感控制启动策略 - 最小可复现实现
// 依赖:ADC读取端电压、定时器产生PWM、GPIO控制换相
// 硬件:三相逆变器 + PMSM + 分压电阻网络(端电压检测)
typedef struct {
uint8_t step; // 当前换相步(0-5)
uint16_t pwm_duty; // PWM占空比
uint16_t period_us; // 换相周期(决定电频率)
uint8_t state; // 0=定位, 1=强拖, 2=闭环
uint16_t bemf_counter; // 过零计数
} FOC_Start_t;
FOC_Start_t motor = {0, 3000, 20000, 0, 0};
// 六步换相表:A+/B- → A+/C- → B+/C- → B+/A- → C+/A- → C+/B-
const uint8_t comm_table[6][3] = {
{1,0,0, 0,1,0}, // 步骤0: AH-BL
{1,0,0, 0,0,1}, // 步骤1: AH-CL
{0,1,0, 0,0,1}, // 步骤2: BH-CL
{0,1,0, 1,0,0}, // 步骤3: BH-AL
{0,0,1, 1,0,0}, // 步骤4: CH-AL
{0,0,1, 0,1,0} // 步骤5: CH-BL
};
// 端电压过零检测(悬空相)
uint8_t check_bemf_zero(uint8_t step) {
// 根据当前步骤确定悬空相
uint8_t floating_phase = (step + 2) % 3; // 0=A, 1=B, 2=C
uint16_t v_phase = adc_read(floating_phase);
uint16_t v_neutral = adc_read(3); // 中性点电压
// 过零判定:端电压穿越中性点电压
static uint16_t last_v_phase = 0;
uint8_t crossing = 0;
if ((last_v_phase - v_neutral) && (v_phase - v_neutral)) {
if (((last_v_phase > v_neutral) && (v_phase < v_neutral)) ||
((last_v_phase < v_neutral) && (v_phase > v_neutral))) {
crossing = 1;
}
}
last_v_phase = v_phase;
return crossing;
}
// 换相延时补偿:过零后延时30°电角度
void delay_30deg(uint16_t period_us) {
uint32_t delay_us = period_us / 12; // 30°/360° = 1/12周期
delay_us(delay_us);
}
// 主控制函数(定时器中断调用,周期=period_us/6)
void motor_control_isr(void) {
switch(motor.state) {
case 0: // 定位:施加固定矢量500ms
set_commutation(0);
motor.pwm_duty = 2000;
if (timer_count > 500) { // 500ms后进入强拖
motor.state = 1;
motor.period_us = 20000; // 初始频率50Hz电频率
timer_count = 0;
}
break;
case 1: // 开环强拖
// 频率递增:每100ms减少换相周期(加速)
if (timer_count % 100 == 0 && motor.period_us > 5000) {
motor.period_us -= 500; // 逐步加速
}
// 执行换相
motor.step = (motor.step + 1) % 6;
set_commutation(motor.step);
// 检测反电动势过零(在换相后30°处检测)
if (check_bemf_zero(motor.step)) {
motor.bemf_counter++;
// 连续3次有效过零则认为可切换
if (motor.bemf_counter >= 3) {
motor.state = 2; // 切换至闭环
}
}
break;
case 2: // 闭环运行(过零换相)
// 等待过零事件,然后延时30°换相
if (check_bemf_zero(motor.step)) {
delay_30deg(motor.period_us);
motor.step = (motor.step + 1) % 6;
set_commutation(motor.step);
}
break;
}
}
// 换相执行
void set_commutation(uint8_t step) {
// 根据comm_table设置三相桥臂PWM
for (int i = 0; i < 6; i++) {
pwm_set_duty(i, comm_table[step][i] ? motor.pwm_duty : 0);
}
}
运行与验证
硬件连接:三相逆变器输出接PMSM,端电压经电阻分压(1kΩ/10kΩ)接ADC引脚,中性点电压接另一ADC通道。PWM频率20kHz,死区2μs。
验证步骤:
- 电机静止时上电,观察转子是否对齐至定位角度(轻微抖动后静止);
- 强拖阶段:用示波器观察端电压波形,应看到梯形波反电动势逐渐增大;
- 闭环切换:监控bemf_counter变量,达到3次过零后state变为2;
- 可靠性验证:在电机轴上加5%额定负载,启动成功率应≥95%(连续启动20次,失败≤1次);
- 记录启动时间(从定位到闭环切换)应小于2秒。
通过判定:电机能稳定从静止加速至额定转速的20%以上并完成闭环切换,切换瞬间无失步、无过流(母线电流不超过额定值1.5倍),带载启动成功率高。
常见问题
- 启动失败/失步:加速斜率过快,增大period_us递减间隔或减小递减量;
- 过零检测误触发:PWM关断期间采样(同步采样),或增加软件滤波(连续2次一致才确认);
- 切换冲击:闭环切换前确保pwm_duty与当前转速匹配,必要时切换时平滑调整占空比。