第三讲:电机驱动层核心——步进序列生成、细分控制原理、电流环与速度环概念
好,我们直接进入正题。这一讲是电机驱动层的核心内容。说白了,就是让电机转起来,并且转得稳、转得准。我见过不少工程师,代码写得飞起,但电机一跑就抖得像筛子。问题出在哪?就是这一层没吃透。
一、步进序列生成——电机转动的“节拍器”
步进电机怎么转?靠的是定子线圈依次通电。这个通电的顺序,就是步进序列。你想想看,就像四个人抬轿子,谁迈左脚、谁迈右脚,顺序错了轿子就翻了。
最基本的序列是单四拍: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占满了,其他任务全卡死。
三、电流环——让电机“有力”且“不烫”
步进电机是电流驱动器件。你给它多少电流,它就出多少转矩。但问题来了:电流太大,电机发热;电流太小,容易丢步。怎么办?闭环控制。
电流环的基本结构:
- 采样:通过采样电阻检测实际电流
- 比较:目标电流 vs 实际电流,算出误差
- 调节:用PI控制器调整PWM占空比
- 输出:更新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个脉冲的位置:
- 位置环算出当前位置和目标位置的差值,输出目标速度
- 速度环根据目标速度和实际速度的差值,输出目标电流
- 电流环根据目标电流和实际电流的差值,调整PWM占空比
这样一层层下来,电机就能精准、平稳地到达目标位置。我在做工业机械臂时,就是用的这种架构,定位精度能达到0.01°。
嗯,最后说一句。这一层是电机驱动的灵魂。你代码写得再花哨,电流环调不好,电机就是抖。我建议你在调试时,先用示波器看电流波形,调好电流环再调速度环。顺序别搞反了。