📖 第 17 章:步进电机 S形加减速(S-Curve Acceleration/Deceleration)

⚙️ 正点原子《DMF407 电机控制专题教程》V1.0 · Chapter 17
🗨️ 本章金句:「梯形够快但不够柔:S 形让「加速度也有加速度」,换一个丝滑的启停。」
这一章在干嘛? 梯形加减速在变速转折点不平滑,启动/停止冲击大。S 形曲线把加速度也做成渐变,冲击噪音更小、启停更柔和,适合精密搬运。本章用五段式模型 + 查表法实现,适合资源紧张的嵌入式系统。
17.1 从梯形到 S 形17.2 原理:加加速度 J 与速度表17.3 控制实现:中断查表输出

17.1 从梯形到 S 形

传统 S 曲线是七段式(加加速、恒加速、减加速、匀速、加减速、恒减速、减减速),参数复杂。本章简化为五段式并令 T1=T2、T4=T5:

原书图 17.2.1
原书图 17.2.1:S 曲线加减速七段式模型
原书图 17.2.2
原书图 17.2.2:S 曲线加减速五段式模型

五段:加加速段(加速度 a 从 0 升到最大)→ 减加速段(a 从最大降回 0,速度仍在增加)→ 匀速 → 加减速 → 减减速。减速段与加速段完全对称(速度倒序),只需算一半。

对比梯形S 形
加速度突变(阶跃)连续渐变
冲击/噪音较大
启停耗时
典型应用定长送料、打印机精密工件搬运

17.2 原理:加加速度 J 与速度表

核心量是加加速度 J(加速度的变化率)。加加速段 $a_1 = J_1 t$,积分得 $v_1 = \frac12 J_1 t^2$,再积分得位移:

$$S_1 = \frac{1}{6} J_1 t^3$$

加速度达到最大值时速度恰好走到中点速度 $v_m = \dfrac{v_0+v_t}{2}$,于是 $J_1 = \dfrac{2 v_m}{t_1^2}$。减加速段 $a_2 = -J(t-t_1)$,$v = v_t - \frac12 J (t-t_1)^2$,位移 $S_2 = v_t t - S_1$,加速段总步数 $S = S_1 + S_2$。

S 形比梯形好算的地方: 速度的倒数就是每步周期,$C_n = f_t / v_n$——不需要梯形那套开方递推!程序里离线算好一张「速度表」,中断里查表即可。
/* 生成 S 形速度表:jerk = 2*(vm-vo)/time^2,逐点填表 */
vm = (g_calc_t.vo + g_calc_t.vt) / 2;                    /* 中点速度 */
jerk = fabs(2.0f * (vm - g_calc_t.vo) / (time * time));  /* 加加速度 */
inc_acc_stp = (int32_t)(g_calc_t.vo * time + INCACCELSTEP(jerk, time)); /* S1 */
dec_acc_stp = (int32_t)((g_calc_t.vt + g_calc_t.vo) * time - inc_acc_stp);
velocity_tab = (float*)mymalloc(SRAMIN, (accel_step + 1) * sizeof(float));
ti_cube = 6.0f * 1.0f / jerk;          /* 第 1 步时间: ti^3 = 6*1/jerk */
ti = pow(ti_cube, (1 / 3.0f));
sum_t += ti;
delta_v = 0.5f * jerk * pow(sum_t, 2);
velocity_tab[0] = g_calc_t.vo + delta_v;   /* 第一步速度 */

for (i = 1; i < accel_step; i++) {
    ti = 1.0f / velocity_tab[i-1];         /* 每步时间 ti = 1/Vn-1 */
    sum_t += ti;
    if (i < inc_acc_stp) {                 /* 加加速段 */
        delta_v = 0.5f * jerk * pow(sum_t, 2);
        velocity_tab[i] = g_calc_t.vo + delta_v;
    } else {                               /* 减加速段 */
        delta_v = 0.5f * jerk * pow(fabs(time - sum_t), 2);
        velocity_tab[i] = g_calc_t.vt - delta_v;
    }
}

17.3 控制实现:中断查表输出

状态机 STATE_ACCEL → STATE_AVESPEED → STATE_DECEL → STATE_STOP。速度表动态申请(mymalloc),加减速完成后必须 myfree 释放。翻转模式下比较值再除 2:

case STATE_ACCEL:   /* 中断中查表输出脉冲 */
    Tim_Pulse = T1_FREQ / (*g_calc_t.ptr);   /* Cn = ft / vn,查表 */
    g_calc_t.ptr++;
    Toggle_Pulse = (uint16_t)(Tim_Pulse / 2); /* 翻转模式除以 2 */
    if (g_calc_t.step_pos >= g_calc_t.accel_step) {
        myfree(SRAMIN, g_calc_t.accel_tab);   /* 释放加速表内存 */
        g_motor_sta = STATE_AVESPEED;         /* 进入匀速段 */
    }
    break;

实验硬件与第 16 章完全相同(接口三、8 细分 1600 脉冲/圈)。KEY0 开启 S 形加减速(stepmotor_move_rel(V_START, V_END, ACCELTIME, DECELTIME, g_step_angle*SPR)),KEY1/KEY2 增减步数(1~50 循环)。注意:总步数必须 ≥ 加速步数 + 减速步数,否则报「参数设置错误」。现象:与梯形相比启停明显更柔和、冲击更小

🧠 小测验
1. 五段式 S 曲线是哪五段?
加加速段、减加速段、匀速段、加减速段、减减速段;T1=T2、T4=T5,减速段与加速段对称(速度倒序),只需算一半。
2. 加加速度 J 如何确定?
加速度达到最大值时速度恰好为中点速度 vm=(v0+vt)/2,由 J1 = 2vm/t1² 求出;第一步时间满足 ti³ = 6/jerk。
3. S 形每步的定时器计数值怎么算?
速度的倒数即脉冲周期:Cn = ft/vn(翻转模式比较值再除 2)。每步速度直接查预先生成的速度表,无需逐点开方递推。
← 上一篇🏠 顶层目录下一篇 →