4. 启动策略(三段式启动):转子预定位、外同步加速、切换至闭环运行
无传感器BLDC启动,说白了就是个「猜位置」的游戏。
电机静止时,反电动势为零。你没法通过它判断转子在哪。但你又必须给对相序,否则电机要么抖,要么反转,要么直接堵转。
我刚开始做这个项目时,就踩过这个坑。上电直接给PWM,电机嗡嗡响就是不转。后来才明白——启动不是靠运气,而是靠策略。
行业内最成熟的做法,就是三段式启动。我习惯叫它「三步走」:先定位,再硬拖,最后放手让它自己跑。
4.1 第一步:转子预定位
预定位的目的很简单——让转子停在你想要的位置上。
怎么做?给任意两相通电,产生一个固定磁场。转子会被这个磁场吸过去,最终停在那个位置。
举个例子:我让A+、B-通电,电流从A相流入,B相流出。产生的合成磁动势会指向某个固定方向。转子会乖乖转过去,停稳。
关键点:预定位时间要足够长。我一般给300~500ms。太短了转子还没停稳,后面加速就容易失步。
这里有个细节——预定位电流不能太小。电流小了,力矩不够,转子可能被负载摩擦力卡住,停不到指定位置。但也不能太大,否则转子冲过头,来回震荡。
我个人习惯:预定位电流设定为额定电流的30%~50%。这个范围既能保证定位可靠,又不会过热。
小技巧:如果你发现预定位后电机启动方向偶尔不对,可以试试先给一个短脉冲,让转子动一下,再给定位电流。这样能打破静摩擦力的「死锁」。
4.2 第二步:外同步加速
转子定位好了,接下来要把它拖起来。
外同步加速,说白了就是「开环硬拖」。你按照预设的换相频率,强制给电机换相。转子被磁场拖着走,速度慢慢往上提。
这个过程有点像推秋千。你不管秋千本身的节奏,就按自己的频率推。只要频率合适,秋千总能荡起来。
换相频率怎么定?从零开始,逐步增加。我一般用这样一个斜坡函数:
// 外同步加速的换相频率计算
// target_freq: 目标切换频率(Hz)
// accel_time: 加速时间(s)
// current_time: 当前已加速时间(s)
float calc_commutation_freq(float target_freq, float accel_time, float current_time) {
if (current_time >= accel_time) {
return target_freq; // 加速完成
}
// 线性斜坡
float freq = target_freq * (current_time / accel_time);
// 最低频率限制,防止启动时频率太低导致抖动
if (freq < 5.0f) {
freq = 5.0f;
}
return freq;
}
加速时间怎么选?我踩过的坑是——加速太快,电机失步;加速太慢,启动过程太长,用户觉得卡顿。
我的经验值:
| 负载类型 | 加速时间 | 说明 |
|---|---|---|
| 轻载(风扇、泵类) | 0.5~1.0秒 | 惯性小,可以快一点 |
| 中载(压缩机) | 1.0~2.0秒 | 需要克服气体压力 |
| 重载(电动工具) | 2.0~3.0秒 | 惯性大,要慢慢来 |
注意:外同步阶段,你是在「盲推」。没有反电动势反馈,你不知道转子实际跟没跟上。所以换相频率的斜率不能太陡。我曾经把加速时间设成0.3秒,结果电机直接啸叫——那是失步的声音。
嗯,这里还要注意一点:外同步阶段的PWM占空比要适当提高。因为开环状态下,电机效率低,需要更多能量才能拖起来。我一般比闭环时的占空比高10%~20%。
4.3 第三步:切换至闭环运行
这是三段式启动里最微妙的一步。
外同步加速到一定速度后,反电动势信号已经足够强了。这时候你要从「开环盲推」切换到「闭环反馈」。切换时机不对,电机要么掉速,要么直接停转。
切换条件是什么?两个:
- 速度足够高:一般需要达到额定转速的10%~20%。具体看电机参数,我习惯等反电动势幅值达到5V以上再切换。
- 信号稳定:反电动势过零检测的信号要连续稳定出现3~5次。不能有毛刺或漏检。
切换过程怎么实现?我常用的方法是「软切换」:
// 三段式启动 - 切换控制
// state: 0=预定位, 1=外同步加速, 2=切换中, 3=闭环运行
void motor_start_control(void) {
static uint8_t start_state = 0;
static uint32_t bemf_stable_count = 0;
switch (start_state) {
case 0: // 预定位
do_pre_position();
if (pre_position_done()) {
start_state = 1;
}
break;
case 1: // 外同步加速
do_openloop_accel();
// 检测反电动势是否稳定
if (bemf_detected()) {
bemf_stable_count++;
if (bemf_stable_count >= 5) {
start_state = 2; // 进入切换
}
} else {
bemf_stable_count = 0;
}
break;
case 2: // 切换中 - 软切换
// 开环占空比逐渐减小,闭环占空比逐渐增大
float openloop_weight = 1.0f - (switch_timer / SWITCH_TIME);
float closedloop_weight = (float)switch_timer / SWITCH_TIME;
pwm_duty = openloop_weight * openloop_duty +
closedloop_weight * closedloop_duty;
if (switch_timer >= SWITCH_TIME) {
start_state = 3; // 切换完成
}
switch_timer++;
break;
case 3: // 闭环运行
do_closedloop_control();
break;
}
}
切换时间SWITCH_TIME我一般设50~100ms。太快了容易冲击,太慢了又拖泥带水。
避坑指南:我曾经在切换时直接丢掉开环占空比,换成闭环计算值。结果电机转速瞬间掉下来,因为闭环刚开始算出来的占空比偏小。后来改成软切换,用加权平均过渡,问题就解决了。
4.4 三段式启动的完整流程图
下面这张图是我自己总结的,把整个启动流程串起来了。你想想看,每一步的输入输出都很清楚:
4.5 实际调试中的几个坑
三段式启动看起来简单,实际调试时问题不少。我把自己踩过的坑列出来,你遇到了可以少走弯路:
- 预定位后转子抖动——定位电流太大,转子过冲。解决办法:减小定位电流,或者加一段「刹车时间」让转子停稳。
- 外同步加速时电机啸叫——换相频率变化太快,转子跟不上。解决办法:延长加速时间,或者用S形曲线代替线性斜坡。
- 切换瞬间转速掉下来——闭环初始占空比计算偏小。解决办法:用软切换过渡,或者把闭环初始占空比设成开环最后时刻的值。
- 重载启动失败——外同步力矩不够。解决办法:提高外同步阶段的占空比,或者增加预定位电流。
我的习惯:调试时先把三段式启动的每个阶段单独测试。预定位看转子停的位置对不对,外同步看转速能不能平稳上升,切换看反电动势信号是否连续。每个阶段都调好了,再连起来跑。这样出问题能快速定位。
嗯,三段式启动就讲到这里。说白了就是三个字:定、拖、切。每个环节都有细节,但掌握了核心逻辑,剩下的就是根据具体电机和负载去调参数了。
公众号:蓝海资料掘金营,微信deep3321