1 对极转子转一圈,每个霍尔输出 1 个完整脉冲(N 极靠近输出 1、S 极输出 0)。统计高电平持续时间就能算转速:


本教程电机是 2 对极:高低电平各持续 360° 电角度,一圈 4 次跳变,故 $n = \dfrac{F_t}{4C} \times 60$。程序在 18kHz(55µs)的定时器中断里累计跳变间隔计数 count_j,速度 = SPEED_COEFF / count_j,再经一阶低通滤波(系数 0.2379)。
速度环参数 KP=0.00800、KI=0.00025、KD=0.00020,采样周期 40ms,积分/输出限幅 ±4000;PID 输出再低通滤波(0.085)后取绝对值作占空比,符号决定方向。
/* 55us 定时器中断:霍尔测速 + 不换相超时保护 */
g_bldc_motor1.count_j++; /* 18K 计数即霍尔脉冲频率 */
g_bldc_motor1.hall_sta_edge = uemf_edge(g_bldc_motor1.hall_single_sta);
if (g_bldc_motor1.hall_sta_edge == 0) { /* 霍尔跳变:算速 */
if (g_bldc_motor1.dir == CW)
temp_speed = (SPEED_COEFF / g_bldc_motor1.count_j);
else
temp_speed = -(SPEED_COEFF / g_bldc_motor1.count_j);
FirstOrderRC_LPF(g_bldc_motor1.speed, temp_speed, 0.2379f);
g_bldc_motor1.count_j = 0;
}
if (g_bldc_motor1.hall_sta_edge == 2) { /* 霍尔一直不变=未换向 */
g_bldc_motor1.no_single++;
if (g_bldc_motor1.no_single > 15000) { /* 超时判定 */
g_bldc_motor1.no_single = 0;
g_bldc_motor1.speed = 0;
}
}
按键:KEY0 目标速度 +400RPM(上限 4000),KEY1 −400RPM(正负定转向),KEY2 停机。现象:橙线先变,红线逐渐逼近——与直流有刷速度环如出一辙。
电流环反馈用母线电流(第 23 章:两个导通相电流之和)。电流环参数 KP=2.00、KI=0.20、KD=0.01。两个关键机制:
if (motor_pwm_c > motor_pwm_sl) { /* 电流环输出大 -> 用速度环输出 */
g_bldc_motor1.pwm_duty = motor_pwm_sl;
if (motor_pwm_s < 0) g_current_pid.Ui = -g_speed_pid.Ui; /* 积分接力 */
else g_current_pid.Ui = g_speed_pid.Ui;
} else { /* 否则用电流环输出 */
g_bldc_motor1.pwm_duty = motor_pwm_c;
if (motor_pwm_s < 0) g_speed_pid.Ui = -g_current_pid.Ui;
else g_speed_pid.Ui = g_current_pid.Ui;
}