这一章在干嘛?

步进电机开环控制便宜简单,但突加负载、快速启停会 丢步/堵转 且控制器毫不知情。给它装上编码器 + PID 位置环,丢一步纠一步,精度和可靠性双升级。

20.1 为什么步进电机也要闭环

20.2 位置闭环原理与关键参数

20.3 控制实现与验证

20.1 为什么步进电机也要闭环

开环的隐含假设是「脉冲数 = 转角,永远成立」。现实中机械老化、突加较大负载快速启停都会打破它——定子磁场跑太快,转子跟不上,就是失步;负载太大拖不动,就是堵转。控制器发出去的脉冲管不了实际转角,高精度场合不能忍。

原书图 20.2.1 原书图 20.2.1:步进电机闭环系统控制原理:编码器反馈实际位置,PID 纠偏

方案优点缺点
开环价格低、控制简单无反馈不能纠偏、可靠性低
闭环(电机+编码器+PID)精度高、消除位置误差、噪音明显降低价格贵、控制复杂

20.2 位置闭环原理与关键参数

结构就是第 12 章的位置环换了个执行器:编码器反馈实际位置 → 与目标求偏差 → PID → 输出「期望脉冲速度」作用于步进电机。关键换算参数:

含义
PULSE_REV1600步进电机每圈脉冲数(8 细分)
ENCODER_SPR2400编码器每圈计数:600 线 × 4 倍频
MPR5丝杠导程 5mm/r
PPM4802400/5 = 每毫米编码器脉冲数
FEEDBACK_CONST1600/2400编码器脉冲 → 步进脉冲的换算比值

PID 参数 L_KP=0.5、L_KI=0.05、L_KD=0,采样周期 20ms(TIM6);积分限幅 ±20、输出限幅 ±150。PID 输出的是「编码器脉冲期望值」,经 FEEDBACK_CONST 换算成步进脉冲数,再算每个脉冲的时间:

20.3 控制实现与验证

/* TIM6 更新中断(20ms 一次) */
if (g_run_flag) {
    g_step_motor.location = gtim_get_encode();       /* 读编码器实际位置 */
    g_motor_pwm = increment_pid_ctrl(&g_location_pid,
                     g_step_motor.location);
    (g_motor_pwm > 0) ? (g_step_motor.dir = CW) : (g_step_motor.dir = CCW);
    g_motor_pwm = abs(g_motor_pwm);                  /* 方向由符号决定 */
    stepper_motion_ctrl(g_step_motor.dir, g_motor_pwm);  /* 作用于电机 */
}

速度换算:

RPM = 编码器脉冲差 × (1000/20) × 60 / 2400。波形呈斜线是因为对步进电机做了限速——PID 输出期望值受限,每次位置增量一致,所以速度曲线是匀速斜坡。

实验:接口三驱动步进电机(TIM8_CH3=PI7),编码器接 TIM3(PC6/PC7),驱动器 8 细分、12~50V 供电。KEY0 启动/停止,KEY1 目标 +20×PPM(上限 60×PPM),KEY2 −20×PPM,初始目标 50×PPM(约 50mm)。可用 PID 调试助手在线整定并看波形:按 KEY0 后电机平稳转到目标位置,曲线近似斜线。