之前使用有硬體浮點單元的微控制器,就一直在用浮點pid,最近在stm32f1上面跑foc,再使用浮點肯定是不太合適的了,就研究了下stm32官方的定點pid。由於foc演算法一般使用pi就夠了,所以下面演算法只有pi(比例,積分)部分,沒有加入d(微分)部分。
typedef
struct
mc_pid_t;
st的**喜歡用h開頭表示16位資料,w開頭表示32位資料,對於需要做定點乘法的**來說,這種表示方法能避免出錯,所以我們這裡沿用這種表示方法。
變數名含義
h_kp
當前使用的kp值
h_ki
當前使用的ki值
w_integral_term
積分項的值,由於積分項需要累加,所以將其值儲存在結構體中
w_upper_integral_limit
積分項的最大值
w_lower_integral_limit
積分項的最小值
h_upper_output_limit
輸出的最大值
h_lower_output_limit
輸出的最小值
h_kp_divisor_pow2
比例項右移的位數
h_ki_divisor_pow2
比例項右移的位數
在我們使用浮點pid演算法時,kp,ki的值我們都能夠設定成小數,而定點不行。那怎麼處理呢?最簡單的辦法就是,將比例項和積分項都除以乙個數,如果kp為1,除以10就相當於kp是0.1了。
在stm32這樣的微控制器中,進行除法運算效率也是比較低的,所以採用右移運算,右移1位表示除以2,右移2位表示除以2^2,一次類推。。。我們變數名中的pow2就是這個意思了,表示以2為底數,變數值為指數的冪。
int16_t mc_pi_controller
(mc_pid_t *pid, int32_t w_process_var_error)
else}}
else}}
// 限制積分項範圍
if(w_integral_sum_tmp > pid->w_upper_integral_limit)
else
if(w_integral_sum_tmp < pid->w_lower_integral_limit)
else
}/* 3 - 計算pid運算的輸出 */
/* 注意:下面這行**不滿足 misra規範;使用者需要驗證編譯器是使用cortex-m3 asr(算術右移指令)而不是
lsr(邏輯右移指令)來處理右移操作,否則結果會得到錯誤的結果。
筆者驗證過,絕大多數arm系列的編譯器(gcc armcc armclang),對於這行**都會使用asr,如不需要進行misra認證,這裡可以放心使用。 */
w_output_32 =
(w_proportional_term >> pid->h_kp_divisor_pow2)
+(pid->w_integral_term >> pid->h_ki_divisor_pow2)
;// 限制pid輸出的範圍
if(w_output_32 > h_upper_output_limit)
else
if(w_output_32 < h_lower_output_limit)
else
pid->w_integral_term +
= w_discharge;
return
((int16_t)
(w_output_32));
}
**中都加入了注釋,直接看**中的注釋就好啦。 pid演算法 pid控制原理
pid控制原理和特點 工程實際中,應用最為廣泛調節器控制規律為比例 積分 微分控制,簡稱pid控制,又稱pid調節。pid控制器問世至今已有近70年歷史,它以其結構簡單 穩定性好 工作可靠 調整方便而成為工業控制主要技術之一。當被控物件結構和引數不能完全掌握,或不到精確數學模型時,控制理論其它技術難...
PID演算法知識
基本思想 pid演算法不但考慮控制物件當前狀態 現在狀態 而且還考慮控制物件過去一段時間的狀態值 歷史狀態 和最近一段時間的狀態值變化 預期 由這3方面共同決定當前的輸出控制訊號。一.計算 pidout pout iout dout pout kp ek out0.其中kp為比例係數,ek sv p...
模糊PID演算法
在講解模糊pid前,我們先要了解pid控制器的原理 本文主要介紹模糊pid的運用,對pid控制器的原理不做詳細介紹 pid控制器 比例 積分 微分控制器 是乙個在工業控制應用中常見的反饋迴路部件,由比例單元p 積分單元i和微分單元d組成。pid控制的基礎是比例控制 積分控制可消除穩態誤差,但可能增加...