三相 120° 通电方式下任意时刻两相通电、一相浮空。浮空相的端电压反映它的反电动势(BEMF,梯形波):

无感检测方法还有反电动势积分法、续流二极管法、三次谐波法、扩展卡尔曼滤波、状态观测器等,反电动势过零检测最成熟。
Y 形绕组没有中性点引出线,就用三个等值电阻构造「虚拟中性点」;驱动板上的比较器(U8B)把浮空相端电压与虚拟中性点电压比较,端电压穿越中性点电压的时刻就是过零点,输出 ZERO_U/V/W 三路过零信号。

三相过零信号(正→负、负→正)共 6 种组合,与 6 种导通状态一一对应且固定,写入正/反转两张真值表——检测到过零组合变化,查表就知道下一步该导通哪两相。
反电动势幅值与转速成正比——静止和低速时根本检测不到过零信号,必须先「盲走」:

| 阶段 | 做法 | 关键参数 |
|---|---|---|
| ① 转子预定位 | 任给一组固定通电(U+V−)强行吸住转子 | 占空比 MAX_PWM_DUTY/20,初始延迟 1100×55µs |
| ② 外同步加速 | 强制换相并逐步升频升压(vvvf 法) | Freq_T_Ref -= Freq_T_Ref/15+1,下限 180 |
| ③ 状态切换 | 检测到稳定过零信号后切入闭环 | count_i ≥ 4(约转 2 圈)才认为稳定 |
/* 三段式启动状态机:定位 -> 升频升压加速 -> 过零闭环 */
case 0: /* 定位:固定一相 */
vvvf_sp.Voilage_Ref = (uint16_t)(MAX_PWM_DUTY / 20);
g_bldc_motor1.pwm_duty = vvvf_sp.Voilage_Ref;
m1_uhvl(); /* U+V- 通电预定位 */
vvvf_sp.Freq_T_Ref = 1100; /* 初始换相延迟 55*1100us */
g_zero_ctr_status = 1;
break;
case 2: /* 加速换相(提高换向频率) */
vvvf_sp.Freq_T_Ref -= vvvf_sp.Freq_T_Ref / 15 + 1; /* 递减延迟=升频 */
change_voltage(); /* 同步升压 */
if (vvvf_sp.Freq_T_Ref < 180) /* 频率下限 */
vvvf_sp.Freq_T_Ref = 180;
anwerfen_sw(); /* 按序换相 */
break;
case 3:
hallless_sw(); /* 切换至闭环过零检测 */
break;过零信号先过一道软件滤波(移位队列 + 掩码):连续多次相同电平才承认,消除换相尖峰的干扰:
hallless_three.Queue_Status[0] = hallless_three.Queue_Status[0] << 1;
hallless_three.Queue_Status[0] |= HAL_GPIO_ReadPin(HALL1_TIM_CH1_GPIO,
HALL1_TIM_CH1_PIN); /* U 相过零点 */
hallless_three.Filter_Math = hallless_three.Queue_Status[0] & FILTER_LONG;
if (hallless_three.Filter_Math == FILTER_LONG)
hallless_three.QFilter_Status[0] = 1; /* 连续为 1 判高 */
else if (hallless_three.Filter_Math == 0x00)
hallless_three.QFilter_Status[0] = 0; /* 连续为 0 判低 */
else { hallless_three.Filter_Count++; return 0; } /* 跳变期不处理 */延迟 30° 怎么算? 未来测不到,但上一个换相周期(60° 电角度)可测,取一半近似:代码实现为 Filter_Delay = count_j / 6。由于硬件低通滤波与软件延迟的叠加,实际延迟角要小于 30°,可用示波器经 PE1 观察校准。
if (hallless_three.Hallless_State != hallless_three.OldHallless_State)
hallless_three.Filter_Count_All++; /* 开始过零计时 */
if (hallless_three.Filter_Count_All >= hallless_three.Filter_Delay)
{ /* 30° 延迟到 */
hallless_three.Filter_Count_All = 0;
if (hallless_three.Hallless_State != hallless_three.OldHallless_State)
{
if (g_bldc_motor1.dir == CCW) g_bldc_motor1.pos--;
else g_bldc_motor1.pos++;
pfunclist_m1[hallless_three.Hallless_State - 1](); /* 查表换相 */
}
hallless_three.OldHallless_State = hallless_three.Hallless_State;
}实验:JP3 跳线帽必须接 H&Z 与 ZERO(不是 HALL);按键 KEY0 正转、KEY1 反转、KEY2 停止。现象:KEY0 后电机经短暂定位-加速后平稳正转。