1. 案例1
任务定义
本案例面向一个一阶惯性加纯延迟的模拟被控对象(例如直流电机转速环),要求通过串口以文本帧格式输出PID控制器的设定值、反馈值与控制量,在PC端串口终端或绘图工具中观察阶跃响应曲线。手动调整Kp、Ki、Kd三个参数,使系统满足:超调量≤10%,稳态误差≤2%,调节时间(进入±5%误差带)≤1.5s。代码在STM32F103系列MCU上运行,通过USART1以115200-8-N-1输出调试数据。
被控对象与控制器模型
被控对象传递函数为G(s)=1/(0.5s+1)·e^(-0.1s),采用零阶保持器离散化,采样周期Ts=10ms。PID控制器采用位置式算法,输出限幅[-100,100],积分分离与抗积分饱和通过输出限幅自然实现。代码中直接给出被控对象差分方程,不依赖外部硬件即可在开发板上运行并产生响应数据。
核心代码实现
#include <stdio.h>
#include <stdint.h>
// 串口发送字符串(需根据实际MCU驱动实现)
void USART_SendString(char* s) {
while(*s) {
// 阻塞发送单个字符至USART1数据寄存器
// 实际项目中替换为寄存器操作或HAL库函数
s++;
}
}
// 被控对象参数(离散化后)
static float y = 0.0f; // 系统输出(反馈值)
static float y_prev = 0.0f; // 上一拍输出
static float u = 0.0f; // 控制器输出
static float e_prev = 0.0f; // 上一拍误差
static float integral = 0.0f;// 积分项累加值
// PID参数(手动调整区域)
#define KP 1.2f
#define KI 0.8f
#define KD 0.05f
// 目标值阶跃
#define SETPOINT 50.0f
// 被控对象差分方程:y[k]=0.8187*y[k-1]+0.1813*u[k-2]
// 对应G(s)=1/(0.5s+1)离散化后并加入一拍纯延迟
void PlantUpdate(float control) {
static float u_delay1 = 0.0f;
static float u_delay2 = 0.0f;
u_delay2 = u_delay1;
u_delay1 = control;
y = 0.8187f * y_prev + 0.1813f * u_delay2;
y_prev = y;
}
// 位置式PID计算
float PID_Compute(float setpoint, float feedback) {
float error = setpoint - feedback;
integral += error;
// 输出限幅[-100,100]
float out = KP * error + KI * integral + KD * (error - e_prev);
e_prev = error;
if(out > 100.0f) out = 100.0f;
if(out < -100.0f) out = -100.0f;
return out;
}
// 模拟控制周期10ms
void ControlLoop(void) {
u = PID_Compute(SETPOINT, y);
PlantUpdate(u);
// 串口输出:设定值,反馈值,控制量
char buf[64];
sprintf(buf, "%.1f,%.1f,%.1f\n", SETPOINT, y, u);
USART_SendString(buf);
}
int main(void) {
// 初始化系统时钟、USART1(115200-8-N-1)
// 初始化定时器中断,每10ms调用一次ControlLoop()
// 此处为演示结构,实际需配置中断
while(1) {
// 主循环空转,控制由定时器中断驱动
}
return 0;
}
参数整定步骤与判定标准
将代码烧录至开发板后,打开串口终端(如PuTTY、串口助手)或使用Python脚本读取串口数据并实时绘图。观察阶跃响应曲线,按以下顺序调整:
- 先置Ki=0,Kd=0,仅用Kp从0.5开始逐步增大,观察响应速度与振荡情况,直至出现临界振荡(持续等幅振荡),记录此时Kp值;
- 取Kp为临界值的0.6倍,加入Ki(初始0.2),逐步增大以消除稳态误差,注意观察超调量;
- 若超调过大,加入Kd(初始0.01),逐步增大以抑制超调,同时观察是否引入高频噪声;
- 重复微调直至满足:超调量≤10%,稳态误差≤2%(即稳态值在49~51之间),调节时间≤1.5s(从阶跃开始到输出进入并保持在47.5~52.5范围内)。
验证方法
在串口终端中观察输出数据流,记录从阶跃开始到响应稳定的时间戳与数值。将数据导入Excel或MATLAB,绘制响应曲线,测量超调量(峰值-设定值)/设定值×100%、稳态误差(稳态均值-设定值)以及调节时间。若三项指标均满足要求,则整定完成。若无法满足,检查被控对象模型参数是否与代码一致,或调整PID参数搜索范围。
调试观测点说明
上图中串口数据帧以CSV格式输出,便于直接导入Excel或绘图工具。响应曲线中蓝色虚线为设定值50,红色实线为系统输出。观测重点:①输出首次到达50的时刻对应延迟时间;②峰值与50的差值计算超调量;③进入±5%误差带(47.5~52.5)后不再超出即为调节时间终点;④稳态后输出均值与50的偏差为稳态误差。若曲线发散或持续振荡,应立即减小Kp或Ki。