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