📖 第 12 章:直流有刷电机位置环控制实现(Position Loop Control)

⚙️ 正点原子《DMF407 电机控制专题教程》V1.0 · Chapter 12
🗨️ 本章金句:「位置环的字典里只有两个词:目标计数,实际计数。」
这一章在干嘛? 用编码器累计计数当「位置」,让电机精确转到指定角度并停住。你按一次按键,电机就多转一圈——不多不少,这就是位置闭环的魅力。
12.1 位置环控制原理12.2 程序设计12.3 下载验证

12.1 位置环控制原理

「位置」就是 TIM3 编码器模式的计数值 + 溢出累计值(正转加、反转减,由 CR1 的 DIR 位判断),每 5ms 读一次存入 g_motor_data.location。它与转角严格成正比:

原书图 12.1.1
原书图 12.1.1:位置环 PID 控制流程:目标位置与实际位置求偏差
$$\text{电机旋转圈数} = \frac{\text{目标计数值变化量}}{44 \times 30} = \frac{\Delta N}{1320}$$

编码器 44 脉冲/圈 × 减速比 30 = 1320 个计数对应输出轴一圈。按键每按一次目标 ±1320 就是 ±1 圈,限位 ±6600(最多正/反 5 圈)。

为什么 KI = 0? 本实验用纯 P + D(KP=15.0、KI=0、KD=7.5,增量式)。定位系统怕的是「冲过头再拉回来」的抖动,积分会加剧超调,干脆不要;稳态误差靠 D 和死区兜底。

12.2 程序设计

/* TIM6 更新中断:位置闭环 */
else if (htim->Instance == TIM6) {
    int Encode_now = gtim_get_encode();
    speed_computer(Encode_now, 5);          /* 速度只用于显示 */
    g_motor_data.location = Encode_now;     /* 计数总值 = 位置反馈 */
    if (val % SMAPLSE_PID_SPEED == 0) {     /* 50ms 一次 */
        if (g_run_flag) {
            motor_pwm_temp = increment_pid_ctrl(&g_location_pid,
                             g_motor_data.location);
            /* 输出低通 0.5/0.5 后限幅 ±4200(比速度环小:定位不需要飙车) */
            g_motor_data.motor_pwm = (int32_t)((g_motor_data.motor_pwm * 0.5)
                                    + (motor_pwm_temp * 0.5));
            if (g_motor_data.motor_pwm >= 4200)
                g_motor_data.motor_pwm = 4200;
            else if (g_motor_data.motor_pwm <= -4200)
                g_motor_data.motor_pwm = -4200;
            motor_pwm_set(g_motor_data.motor_pwm);
        }
        val = 0;
    }
    val++;
}

按键逻辑:KEY0 目标 +1320(正转一圈)、KEY1 −1320、KEY2 目标清零(回初始位置)。输出可正可负,PID 自动决定正转还是反转去逼近目标。

12.3 下载验证

上位机用 debug_set_point_range(6600, -6600, 6600) 限定目标范围;HALT 命令回原点,RUN 命令目标 1320(一圈)。每 200ms 上传一次编码器总计数值。

原书图 12.4.1
原书图 12.4.1:位置环 PID 控制波形:红线(实际位置)逼近橙线(目标位置)后稳稳停住
现象解读: 按一次 KEY0,橙线跳一格(1320),红线平滑爬升到目标后纹丝不动;按 KEY2 目标归零,电机自己倒回原点。如果最后停在目标附近轻微抖动,检查是否漏配死区或 KD 太小。
🧠 小测验
1. 本实验用什么物理量表示电机「位置」?
编码器计数总值:TIM3 编码器模式计数值加上中断里按 DIR 位累计的溢出值,存入 g_motor_data.location。
2. 目标计数值增加 1320 意味着什么?怎么算的?
输出轴正转一圈。电机旋转圈数 = 计数变化量 / 44 / 30,44(编码器脉冲)× 30(减速比)= 1320。
3. 位置环为什么不用积分(KI=0)?
定位系统怕超调抖动,积分会累积加剧超调;纯 P+D 已能到位,剩余小偏差用死区消除即可。
← 上一篇🏠 顶层目录下一篇 →