PID(比例-積分-微分)控制是工業自動化核心算法。本文提供完整、可編譯運行的 ANSI C 實現,包含結構體設計、初始化、參數整定、無衝擊切換、核心計算與積分抗飽和邏輯。
typedef struct {
int pv; // 過程值
int sp; // 設定值
float integral; // 積分項
float pgain; // 比例增益
float igain; // 積分增益
float dgain; // 微分增益
int deadband; // 死區
int last_error; // 上次誤差
} PID_Controller;
last_error = sp - pv,防止設定值突變導致輸出跳變。float pid_calc(PID_Controller *pid) {
int err = pid->sp - pid->pv;
if (abs(err) > pid->deadband) {
float ferror = (float)err;
float pterm = pid->pgain * ferror;
// 積分抗飽和:比例項過大時清零積分,否則累積並限幅
if (pterm > 100 || pterm < -100) {
pid->integral = 0.0f;
} else {
pid->integral += pid->igain * ferror;
if (pid->integral > 100.0f) pid->integral = 100.0f;
else if (pid->integral < 0.0f) pid->integral = 0.0f;
}
float dterm = (float)(err - pid->last_error) * pid->dgain;
float result = pterm + pid->integral + dterm;
pid->last_error = err;
return result;
}
return pid->integral; // 死區內僅保持積分輸出
}
int main() {
PID_Controller pid = {0};
int pv = 30, sp = 40;
float kp = 5.2f, ki = 0.77f, kd = 0.18f;
int deadband = 2;
pid_init(&pid, pv, sp);
pid_tune(&pid, kp, ki, kd, deadband);
pid_setinteg(&pid, 0.0f);
pid_bumpless(&pid);
for (int i = 0; i < 20; ++i) {
printf("輸入當前過程值 PV: ");
scanf("%d", &pid.pv);
float out = pid_calc(&pid);
printf("PID 輸出: %.2f\n", out);
}
return 0;
}
此代碼結構清晰,適合教學與中小型嵌入式項目移植。實際部署時請根據硬體平台調整數據類型、定時機制與參數整定流程。