typedef struct _PID
{uchar const code ucAddWater_pwm_def[]={80,80,80,70,70,70,60,60,60,55,55};
uchar HeatEnable; //加热使能
float Kp; //比例系数
float Ki; //积分系数
float Kd; //微分系数
float PrevError; //最后第二次误差数Er[-2]
float LastError; //最后 一次误差数Er[-1]
float SumError; //误差积分
float dError; //微分项
float Result;
uchar Max; //限幅
uchar Min; //限幅
uchar HeatState; //加热状态
uchar ConstTempBit; //进入恒温状态
uint PWM_Result; //最终PWM占空比
uint TimeS; //时间(秒)
}xdata PID;
// PID初始化
void Clean_PIDData(PID *pid)
{
pid->Kp = 1;
pid->Ki = 0.2;
pid->Kd = 0.1;
pid->Max = 0;
pid->Min = 0;
pid->PrevError = 0;
pid->LastError = 0;
pid->SumError = 0;
pid->dError = 0;
pid->Result = 0;
pid->HeatState = 0;
pid->PWM_Result = 0;
pid->TimeS = 0;
}
uchar PIDCalc(PID *pp, float reference,float CurrentPoint,float DefPoint)
{
float Error; //偏差
float Calc_Result;
Error = reference - CurrentPoint; //偏差值 = 设定值-输入值(当前值)
pp->SumError += Error; //积分 = 积分+偏差 --偏差的累加
pp->dError = pp->LastError - pp->PrevError;//当前微分 = 最后误差 - 之前误差
pp->PrevError = pp->LastError; //更新“之前误差”
pp->LastError = Error; //更新“最后误差”
if(pp->TimeS==0){pp->TimeS=1;pp->SumError = (PWM_MAX-DefPoint)/pp->Ki;}//开始运算时补偿
LIMIT(pp->SumError,PWM_MIN,PWM_MAX);//积分必须限制
Calc_Result = pp->Kp * pp->LastError //比例项 = 比例常数 * 偏差
+pp->Ki * pp->SumError //积分项 = 积分常数 * 误差积分
+pp->Kd * pp->dError; //微分项 = 微分常数 * 当前微分
pp->Result = Calc_Result;
LIMIT(pp->Result,0,PWM_MAX-PWM_MIN);//输出限幅
pp->Result =(float)PWM_MAX-pp->Result;//最终输出
return Calc_Result;
}
PIDCalc(&pid,uc_Set_Temp,ucOut_Temp,ucAddWater_pwm_def[uc_Set_Temp/10]);