第三讲:电机驱动层核心——步进序列生成、细分控制原理、电流环与速度环概念

好,我们直接进入正题。这一讲是电机驱动层的核心内容。说白了,就是让电机转起来,并且转得稳、转得准。我见过不少工程师,代码写得飞起,但电机一跑就抖得像筛子。问题出在哪?就是这一层没吃透。

一、步进序列生成——电机转动的“节拍器”

步进电机怎么转?靠的是定子线圈依次通电。这个通电的顺序,就是步进序列。你想想看,就像四个人抬轿子,谁迈左脚、谁迈右脚,顺序错了轿子就翻了。

最基本的序列是单四拍:A→B→C→D。但实际项目中我几乎不用这个。为什么?因为转矩太小,而且容易丢步。我习惯用双四拍:AB→BC→CD→DA。这样两个线圈同时通电,转矩能提升40%左右。

核心要点:步进序列决定了电机的旋转方向和步距角。一个完整的电周期对应一个步距角,比如1.8°的电机,走完A→B→C→D四步,转子转过1.8°。

代码实现其实不复杂。我贴一段我常用的序列生成逻辑:

// 双四拍步进序列表
const uint8_t step_sequence[4][2] = {
    {PHASE_A, PHASE_B},  // AB
    {PHASE_B, PHASE_C},  // BC
    {PHASE_C, PHASE_D},  // CD
    {PHASE_D, PHASE_A}   // DA
};

void step_motor(uint8_t direction) {
    static uint8_t step_index = 0;
    if (direction == CW) {
        step_index = (step_index + 1) % 4;
    } else {
        step_index = (step_index + 3) % 4;  // 逆时针
    }
    // 写入GPIO,使能对应相
    write_phases(step_sequence[step_index]);
}

嗯,这里要注意:序列切换的时机由定时器控制。你不能用软件延时,那会阻塞整个系统。我踩过这个坑——早期用delay_ms()做步进,结果电机一转,按键响应就卡死了。

二、细分控制原理——让电机“滑”起来

整步驱动有个问题:低速时振动大,像在跳踢踏舞。细分控制就是来解决这个的。它的本质是什么?把一步拆成多步,用PWM控制电流渐变

举个例子。1.8°的电机,整步走一步就是1.8°。如果做16细分,每一步变成1.8°/16 = 0.1125°。转子走得就更平滑了。

细分的核心是电流分配。我画个简化的正弦波表:

细分步 A相电流 B相电流
0 100% 0%
1 92% 38%
2 71% 71%
3 38% 92%
4 0% 100%

你看,电流不是跳变的,而是按正弦规律变化。这样磁场旋转就平滑了。我在做3D打印机驱动时,用过256细分,电机几乎听不到噪音。

我的经验:细分不是越高越好。256细分虽然平滑,但PWM频率要很高,MCU负担重。一般应用16~64细分就够用了。我曾经为了追求极致平滑,上了512细分,结果PWM中断把CPU占满了,其他任务全卡死。

三、电流环——让电机“有力”且“不烫”

步进电机是电流驱动器件。你给它多少电流,它就出多少转矩。但问题来了:电流太大,电机发热;电流太小,容易丢步。怎么办?闭环控制。

电流环的基本结构:

  1. 采样:通过采样电阻检测实际电流
  2. 比较:目标电流 vs 实际电流,算出误差
  3. 调节:用PI控制器调整PWM占空比
  4. 输出:更新PWM,让电流逼近目标值

我贴一段电流环的简化代码:

void current_loop(void) {
    int16_t target = current_target;  // 来自速度环或位置环
    int16_t actual = read_adc();      // 读取采样电阻电压
    int16_t error = target - actual;
    
    // PI控制器
    static int32_t integral = 0;
    integral += error;
    // 限幅,防止积分饱和
    if (integral > INTEGRAL_MAX) integral = INTEGRAL_MAX;
    if (integral < -INTEGRAL_MAX) integral = -INTEGRAL_MAX;
    
    int32_t output = Kp * error + Ki * integral;
    // 限幅后更新PWM
    set_pwm_duty(output);
}

避坑指南:我曾经在电流环里忘了加积分限幅,结果电机堵转时积分一直累加,PWM占空比冲到100%,采样电阻直接冒烟了。从那以后,我每个PI控制器都加限幅,而且限幅值要留余量。

四、速度环——让电机“匀速”或“变速”

速度环在电流环外面。它的任务是:让电机按你期望的速度转。比如你设定1000RPM,速度环就要保证实际转速稳定在1000RPM附近。

速度环的输入是目标速度,反馈是实际速度(通过编码器或霍尔传感器测得)。输出是电流环的目标电流值。

为什么需要速度环?因为步进电机开环时,负载变化会导致转速波动。比如你带着负载加速,开环可能直接丢步。有了速度环,它会自动增加电流,补偿负载转矩。

我常用的速度环结构:

  • 前馈:根据目标速度估算需要的电流基础值
  • 反馈:PI控制器修正误差
  • 加速度限制:防止速度突变导致过冲

关键点:速度环的响应速度要比电流环慢。一般电流环的周期是50~100μs,速度环可以放到1~5ms。如果两个环跑一样快,系统容易振荡。我习惯让速度环周期是电流环的10~20倍。

五、三环联动——从位置到电流的完整链路

实际项目中,我们通常用三环控制:位置环→速度环→电流环。位置环最慢,电流环最快。

举个例子。你要让电机转到1000个脉冲的位置:

  1. 位置环算出当前位置和目标位置的差值,输出目标速度
  2. 速度环根据目标速度和实际速度的差值,输出目标电流
  3. 电流环根据目标电流和实际电流的差值,调整PWM占空比

这样一层层下来,电机就能精准、平稳地到达目标位置。我在做工业机械臂时,就是用的这种架构,定位精度能达到0.01°。

嗯,最后说一句。这一层是电机驱动的灵魂。你代码写得再花哨,电流环调不好,电机就是抖。我建议你在调试时,先用示波器看电流波形,调好电流环再调速度环。顺序别搞反了。