|
本代碼采用Proteus仿真,采用51單片機模擬PWM,用定時器獲取電機轉速信息,用PID算法控制轉速,轉速、P、I、D都可以用按鈕設置,LCD顯示屏顯示出電機的轉速、差值、設定值、P、I、D,并可以粗調跟微調,還有閃爍提示,用來指示當前的設置項目。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
220817e7exuwgbu0x1kbba.png (16.63 KB, 下載次數: 118)
下載附件
2018-10-10 12:30 上傳
不按設定鍵直接調整的是設定速度值因為速度值是以周期形式調整,所以速度值越小,轉速越高,2秒鐘無操作退出設置模式,非設置模式調節轉速
單片機源程序如下:
- //************************項目信息**************************
- //項目名稱:
- //客戶名稱:
- //************************文件信息**************************
- //文件名稱:pi.c
- //作 者:Lebo
- //文件版本:
- //校 驗 和:
- //************************硬件信息**************************
- //目標器件:
- //源 時 鐘:
- //UCBA型號:
- //************************平臺信息**************************
- //開發環境:
- //燒錄環境:
- //配置內容:
- //************************功能信息**************************
- //程序功能:
- //函數列表:
- //************************修改記錄**************************
- // <author> <time> <version> <desc>
- //1.Lebo 15/01/11 V1.0 build this moudle
- //2.
- //**********************************************************
- //**********************************************************
- //程序名稱:頭文件
- //程序說明:
- //**********************************************************
- #include "pid.h"
- //**********************************************************
- //程序名稱:增量式PID初始化 函數
- //入口參數:*ptrPID
- //出口參數:e0, e1, e2, ka, kb, kc, kz, max_adjust, max_out, min_out
- //返回參數:
- //調用函數:
- //程序說明:
- //**********************************************************
- void PID_IncInit(PID_TypeDef *ptrPID){
- (* ptrPID).e0 = 0;
- (* ptrPID).e1 = 0;
- (* ptrPID).e2 = 0;
-
- (* ptrPID).ka = 0;
- (* ptrPID).kb = 0;
- (* ptrPID).kc = 0;
- (* ptrPID).kz = 0;
-
- (* ptrPID).maxAdjust = 0;
- (* ptrPID).maxOut = 0;
- (* ptrPID).minOut = 0;
- }
- //**********************************************************
- //程序名稱:增量式PID系數設置 函數
- //入口參數:kp, ki, kd, z, *pid_ptr
- //出口參數:ka, kb, kc, kz
- //返回參數:
- //調用函數:
- //程序說明:
- /*
- T--------采樣周期
- Ti-------積分時間
- Td-------微分時間
- Kp = Kp
- Ki = Kp*T/Ti
- Kd = Kp*Td/T
- A = Kp+Ki+Kd = Kp*(1 + T/Ti + Td/T)
- B = Kp+2*Kd = Kp*(1 + 2Td/T)
- C = Kd = Kp*Td/T
- *///120,11,0,10
- //**********************************************************
- void PID_IncSetRatio(u8 kp, u8 ki, u8 kd, u8 kz, PID_TypeDef *ptrPID){
- (* ptrPID).ka = kp + ki + kd;
- (* ptrPID).kb = kp + (2 * kd);
- (* ptrPID).kc = kd;
- (* ptrPID).kz = kz;
- }
- //**********************************************************
- //程序名稱:PID系數極限設置 函數
- //入口參數:max_ajst, max_outval, min_outval, *pid_ptr
- //出口參數:max_adjust, max_out, min_out
- //返回參數:
- //調用函數:
- //程序說明:
- //**********************************************************
- void PID_IncSetRatioLimit(s8 maxAdjust, u8 maxOut, u8 minOut, PID_TypeDef *ptrPID){
- (* ptrPID).maxAdjust = maxAdjust;
- (* ptrPID).maxOut = maxOut;
- (* ptrPID).minOut = minOut;
- }
- //**********************************************************
- //程序名稱:增量式PID 函數
- //入口參數:nonce_error, pid_ptr, out_ptr
- //出口參數:*out_ptr
- //返回參數:
- //調用函數:
- //程序說明:
- /*
- ////位置式PID控制算式
- //// 離散的PID表達式:
- //// U(n) = Kp*{e(n) + (T/Ti)*Sum[e(0)+e(1)...+e(n)] + (Td/T)*[e(n)-e(n-1)]}
- //// U(n) = Kp*e(n) + Ki*Sum[e(0)~e(n)] + Kd*[e(n)-e(n-1)]
- //// 說明:
- //// n--------采樣序號,n=0,1,2,…… 。
- //// U(n)-----第n次采樣時刻的計算輸出量
- //// e(n)-----第n次采樣時刻輸入的偏差值
- //// e(n-1)---第n-1次采樣時刻輸入的偏差值
- //// T--------采樣周期
- //// Ti-------積分時間
- //// Td-------微分時間
- //// Kp-------比例系數
- //// Ki-------積分系數,Ki = Kp*T/Ti
- //// Kd-------微分系數,Kd = Kp*Td/T
- 增量式PID控制算式(廣泛應用)
- 增量式PID控制算法公式:
- dU(n) = U(n)-U(n-1)
- dU(n) = Kp*[e(n)-e(n-1)] + Ki*e(n) + Kd*[e(n)-2*e(n-1)+e(n-2)]
- dU(n) = (Kp+Ki+Kd)*e(n) - (Kp+2*Kd)*e(n-1) + e(n-2)*Kd
- dU(n) = A*e(n) - B*e(n-1) + C*e(n-2)
- 說明:
- T--------采樣周期
- Ti-------積分時間
- Td-------微分時間
- Kp = Kp
- Ki = Kp*T/Ti
- Kd = Kp*Td/T
- A = Kp+Ki+Kd = Kp*(1 + T/Ti + Td/T)
- B = Kp+2*Kd = Kp*(1 + 2Td/T)
- C = Kd = Kp*Td/T
- 由于單片機的處理速度和ram 資源的限制,一般不采用浮點數運算,而將所有參數全部用整
- 數,運算到最后再除以一個2的N次方數據(相當于移位),作類似定點數運算,可大大提高
- 運算速度,根據控制精度的不同要求,當精度要求很高時,注意保留移位引起的“余數”,做
- 好余數補償。
- */
- //**********************************************************
- void PID_IncCompute(s16 offset, u8 *ptrOut, PID_TypeDef *ptrPID){
- s16 outResult = (s16)(* ptrOut);
- s32 median;
- s8 adjust;
- (* ptrPID).e2 = (* ptrPID).e1;
- (* ptrPID).e1 = (* ptrPID).e0;
- (* ptrPID).e0 = offset;
- median = (s32)(* ptrPID).ka * (* ptrPID).e0 -\
- (s32)(* ptrPID).kb * (* ptrPID).e1 +\
- (s32)(* ptrPID).kc * (* ptrPID).e2;
- median = median >> (* ptrPID).kz;
- if(median < -(* ptrPID).maxAdjust)
- adjust = -(* ptrPID).maxAdjust;
- else if(median > (* ptrPID).maxAdjust)
- adjust = (* ptrPID).maxAdjust;
- else
- adjust = (s8)median;
- outResult += adjust;
- if(outResult > (* ptrPID).maxOut)
- outResult = (* ptrPID).maxOut;
- else if(outResult < (* ptrPID).minOut)
- outResult = (* ptrPID).minOut;
- *ptrOut = (u8)outResult;
- }
復制代碼
0.png (47.37 KB, 下載次數: 131)
下載附件
2018-10-10 12:52 上傳
0.png (6.53 KB, 下載次數: 141)
下載附件
2018-10-10 12:54 上傳
所有資料51hei提供下載:
PID Proteus.rar
(172.39 KB, 下載次數: 392)
2018-10-10 12:31 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
評分
-
查看全部評分
|