STM32 标准外设库 PID 示例
面向 STM32F103C8 的标准外设库 PID 教学模板,以及定时器、编码器和 PWM 的接入方法。
本页面是 PID 第一课配套的 STM32 标准外设库示例,面向 STM32F103C8 和 STM32 标准外设库。它参考了课程资料中的综合测试程序,但没有复制或移动原始 Keil 工程。
文件说明
- PID.h:PID 状态结构体和函数声明;
- PID.c:带显式采样周期、积分限幅、条件积分和测量值微分的 PID 核心;
- ControlLoop_SPL.h:控制循环接口声明;
- ControlLoop_SPL.c:展示 TIM1 节拍、编码器反馈和带方向 PWM 的控制循环。
与参考工程的对应关系
参考工程中 TIM1 的计数频率为 1 kHz,因此更新中断周期为 1 ms;Mode21_Tick() 每 40 次中断执行一次 PID,实际控制周期约为 40 ms。参考工程的 PID_Update() 使用误差累加和误差差分,代码短小,适合作为入门版本。
本示例加入了显式采样周期 sample_time,并默认使用测量值微分,从而减少目标值阶跃引起的微分冲击。参数需要根据电机、编码器分辨率、减速比、驱动器限幅和实际采样周期重新整定。
接入现有标准库工程
- 将 PID.h、PID.c、ControlLoop_SPL.h 和 ControlLoop_SPL.c 加入 Keil 工程。
- 保留原工程的
Encoder.c、Motor.c、PWM.c和Timer.c,确认定时器时钟、编码器接线和 PWM 范围一致。 - 在
main.c初始化外设后调用ControlLoop_Init()。 - 在
TIM1_UP_IRQHandler()清除中断标志后调用ControlLoop_On1msTick()。 - 在主循环中反复调用
ControlLoop_Run(),不要在中断里调用阻塞式 ADC、串口打印或复杂显示函数。
调用关系
TIM1 更新中断(1 ms)
│
├─ 每 40 次产生一次控制更新请求
│
├─ TIM3 编码器计数 → 位置差分 → 速度反馈
│
├─ PID_Update() → 带限幅的控制输出
│
└─ Motor_SetPWM() → 方向 GPIO + TIM2 PWM → 电机
使用边界
这个示例是教学模板,不保证不修改引脚和外设配置就能直接烧录到所有 STM32F103 板卡。使用前需要确认芯片型号、定时器时钟、编码器接口、PWM 周期、电机驱动逻辑和反馈单位。