首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C語言PID控制算法完整實現與原理解析

     編輯:C 語言問答

PID 控制器 C 語言實現:從結構體到完整算法

PID(比例-積分-微分)控制是工業自動化核心算法。本文提供完整、可編譯運行的 ANSI C 實現,包含結構體設計、初始化、參數整定、無衝擊切換、核心計算與積分抗飽和邏輯。

核心數據結構

typedef struct {
    int pv;           // 過程值
    int sp;           // 設定值
    float integral;   // 積分項
    float pgain;      // 比例增益
    float igain;      // 積分增益
    float dgain;      // 微分增益
    int deadband;     // 死區
    int last_error;   // 上次誤差
} PID_Controller;

關鍵函數解析

  1. pid_init():綁定 PV/SP 指標(原代碼直接賦值,實際工程常傳遞指針)。
  2. pid_tune():設定 Kp, Ki, Kd, 死區;初始化積分項與上次誤差。
  3. pid_setinteg():手動設定積分初值,用於啟動時無衝擊輸出。
  4. pid_bumpless():無衝擊切換,將 last_error = sp - pv,防止設定值突變導致輸出跳變。
  5. pid_calc():核心位置式 PID 算法,含積分抗飽和(限幅 0-100)與死區判斷。

核心計算邏輯(pid_calc 節錄)

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;
}

工程應用注意事項

  • 采樣時間:位置式 PID 需固定週期調用(如 100ms),否則積分/微分項失真。嵌入式常用定時器中斷觸發。
  • 參數整定:Ziegler-Nichols、試誤法、模型辨識法。
  • 數據類型:嵌入式無 FPU 時常用定點數(Q 格式)替代 float。
  • 抗風up:代碼採用條件限幅法,另有反計算法、飽和回差法等。

總結

此代碼結構清晰,適合教學與中小型嵌入式項目移植。實際部署時請根據硬體平台調整數據類型、定時機制與參數整定流程。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved