新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > PID算法C18程序的實現

        PID算法C18程序的實現

        作者: 時間:2012-09-15 來源:網絡 收藏

        PID 計算資源需求

        DS=Pdu(k)+I t/ti(uk)+ D TD/T duk+du(k-1)

        puk-i *T/TI*uk+d*(uk-2* uk-1 + uk-2)

        三個系統狀態是需要的 UK UK-1 UK-2

        還有P I D 的參數也是需要的

        當然還有個 T (似乎也有人 把積分時間 T 和微分時間T 分開了? 我不是很明白不管他)

        應為不同的硬件體系 我們需要計算數據的位數 有差異(可能需要int型 去算 也可能用 long ,floAt 等)

        應為是C18下的 我先試用INT 去做

        #define PID_TYPE int

        這樣以后換類型也省事

        于是我們定義1個結構體

        struct pid_unit { PID_TYPE pid_sens[3];   // 用來保存 UK UK-1 UK-2 三個時刻的輸出偏差PID_TYPE pid_cpid[3];   // 當然是 P  I  D 三個參數咯PID_TYPE pid_dpid[3];   // P 部分計算值 I部分計算值 D 部分計算值 這三個值相加就是PID 的輸出};初始化PIDvoid pid_init(struct pid_unit *unit, PID_TYPE p,             PID_TYPE i,            PID_TYPE d)              { unit->pid_cpid[0] = p; //PID 比例系數 初始化 沒得說 哈unit->pid_cpid[1] = i; unit->pid_cpid[2] = d; unit->pid_dpid[0] = 0;//P  i  d 個個部分都假定為0  不過實際也是0#24unit->pid_dpid[1] = 0; //unit->pid_dpid[2] = 0; //unit->pid_sens[0] = 0; // 當前差值unit->pid_sens[1] = 0; //unit->pid_sens[2] = 0; //}

        接下來 就是計算部分了

        第一部分 P部分 計算

        unit->pid_dpid[0] = unit->pid_sens[0] * unit->pid_cpid[0]; //就是P*UK

        然后是I部分 。。不過大家會發現I還需要前一次的計算結果。。咋辦。。

        第一次 用的是0。n那么第二次 用的就是現在的咯

        所以要保存現在的值 給下一次用

        同時保存上一次的值 到上上一次

        說的這么拗口,。那是我語文沒學好

        其實就是保存三個時間狀態值

        丟棄最老的 保存最新的

        unit->pid_sens[1] = unit->pid_sens[0];
        unit->pid_sens[0] = input;

        unit->pid_dpid[1] = unit->pid_sens[0] * unit->pid_cpid[1] * time;

        等我吃個飯再來 有點問題
        GOOGLE 源碼是:

        unit->pid_dpid[1] += unit->pid_sens[0] * unit->pid_cpid[1] * time;

        ΔU=U(k)-U(k-1)=Kp*[e(k)-e(k-1)]+Ki*e(k)+Kd*[e(k)-2*e(k-1)+e(k-2)]

        是肯定沒問題的。。所以 似乎GOOGLE 上源碼不對哦,,大家要注意了

        D部分 Kd*[e(k)-2*e(k-1)+e(k-2)


        unit->pid_dpid[2] = ((unit->pid_sens[0] - 2*unit->pid_sens[1]+unit->pid_sens[2])/time) *unit->pid_cpid[2];
        然后對P I D 求和

        unit->pid_dpid[0] + unit->pid_dpid[1] + unit->pid_dpid[2];

        故有PID 計算子函數如下

        PID_TYPE pid_control(struct pid_unit *unit,   PID_TYPE input,          PID_TYPE time)            { // adjust the FIFO preserving the sensor data unit->pid_sens[1] = unit->pid_sens[0]; unit->pid_sens[0] = input; // calculate each pid variable unit->pid_dpid[0]  =  unit->pid_sens[0] * unit->pid_cpid[0]; unit->pid_dpid[1] =  unit->pid_sens[0] * unit->pid_cpid[1] * time; unit->pid_dpid[2]  = (unit->pid_sens[0] - unit->pid_sens[1])/time *unit->pid_cpid[2]; return unit->pid_dpid[0] +  unit->pid_dpid[1] + unit->pid_dpid[2]; } 


        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 阿坝县| 靖州| 闸北区| 江源县| 嘉兴市| 宣威市| 车致| 新绛县| 东至县| 平湖市| 宜春市| 垫江县| 堆龙德庆县| 香河县| 房产| 潼关县| 河源市| 长汀县| 大宁县| 西青区| 凯里市| 廉江市| 上虞市| 个旧市| 潍坊市| 嘉义市| 桑植县| 外汇| 舞阳县| 甘肃省| 辽阳县| 尼木县| 昔阳县| 珲春市| 理塘县| 宣汉县| 吐鲁番市| 文安县| 汾西县| 龙泉市| 桓台县|