void StationPIDFollowCtrl(void)
{
// float display_value;
unsigned char i;
//float MAdata;
const OutTempToMatchTemp_Struct *OutTempToMatchTempPtr;
OutTempToMatchTempPtr = OutTemperatureMatchTable;
EEPROMReadBytes(&StationModeCtrl,0x0D00,4);
/*
set_point = 30;
process_point = 40;
p_gain = (float)(0.067);//5.2
i_gain = (float)(0.77);//
d_gain = (float)(0.18);//
dead_band = 0.01;//2
integral_val =(float)(0.01);
*/
if( StationModeCtrl.CtrlAdjust == 0 )
{
if(PidSetSign == 1)
{
PidSetSign = 0;
//EEPROMReadBytes(&PIDFollowCtrl,0x0E00,26);
pid_tune(&PIDFollowCtrl,
SysConfig.pgain,SysConfig.igain,SysConfig.dgain,SysConfig.deadband);
pid_bumpless(&PIDFollowCtrl);
}
switch (StationModeCtrl.CtrlMode)
{
case 0:
case 1:
PIDFollowCtrl.SP = SysConfig.CtrlTemp;
break;
case 2:
//SysVar.OutsideTemp = -10;
for(i = 0; i < MatchTempNum; i ++)
{
if((SysVar.OutsideTemp >=OutTempToMatchTempPtr->FactTempDownLimit)&&(SysVar.OutsideTemp < OutTempToMatchTempPtr->FactTempUpLimit))
{
PIDFollowCtrl.SP = (int)OutTempToMatchTempPtr->MatchTemp; SysData.MatchingTemp = OutTempToMatchTempPtr->MatchTemp; }
OutTempToMatchTempPtr ++;
}
break;
}
/*
Pid_Init(&PIDFollowCtrl, process_point, set_point);
pid_tune(&PIDFollowCtrl, p_gain,i_gain,d_gain,dead_band); // pid_setinteg(&warm,0.0); //pid_setinteg(&warm,30.0);
//pid_setinteg(&warm,20.0);
pid_bumpless(&PIDFollowCtrl);
display_value = pid_calc(&PIDFollowCtrl);
*/
if(PidChangeRangeSign == 1)
{
PidChangeRangeSign = 0;
if(StationModeCtrl.CtrlAim == 0)
{
FluxGetConfig(2,&FluxConfig);
AI_GetConfig(FluxConfig.Temp1No,&AIConfig);
PIDFollowCtrl.temperaturerange = AIConfig.Max - AIConfig.Min; }
else
{
FluxGetConfig(2,&FluxConfig);
AI_GetConfig(FluxConfig.Temp2No,&AIConfig);
PIDFollowCtrl.temperaturerange = AIConfig.Max - AIConfig.Min; }
}
if(StationModeCtrl.CtrlAim == 0)
{
Pid_Init(&PIDFollowCtrl, SysData.FluxData[1].Temp1, 0);
}
else
{
Pid_Init(&PIDFollowCtrl, SysData.FluxData[1].Temp2, 0);
}
//PIDFollowCtrl.temperaturerange = 150;
display_value = pid_calc(&PIDFollowCtrl);
display_value = display_value*(1/(PIDFollowCtrl.temperaturerange*PIDFollowCtrl.pgain)); MAdata = 12 +16 * display_value;
//AO_Out(1,16);
}
else
{
}
}
//-----------------------------------------------------------------------------
// Subroute Name: Pid_Init
// Create Time: 06.11.7
// Ver: 0.99
// Author: YSF
// Description: 初始化PID
//
// Input: type :
// Output:
//------------------------------------------------------------
void Pid_Init(PIDFollowCtrl_Struct *PIDFollowCtrl, int process_point, int set_point)
{
PIDFollowCtrl_Struct *pid;
pid = PIDFollowCtrl;
pid->PV = process_point;
// pid->SP = set_point;
}
//-----------------------------------------------------------------------------
// Subroute Name: pid_tune
// Create Time: 06.11.7
// Ver: 0.99
// Author: YSF
// Description: 调整比例增益p_gain,积分增益i_gain,微分增益d_gain,和无控制区的PID控制结构
// Input: type :
// Output:
//------------------------------------------------------------
void pid_tune(PIDFollowCtrl_Struct *pid, float p_gain, float i_gain, float d_gain, unsigned int dead_band)
{
pid->pgain = p_gain;
pid->igain = i_gain;
pid->dgain = d_gain;
pid->deadband = dead_band;
pid->integral= integral_val;
pid->last_error=0;
}
//-----------------------------------------------------------------------------
// Subroute Name: pid_setinteg
// Create Time: 06.11.7
// Ver: 0.99
// Author: YSF
// Description: 为PID平衡的积分设定一个新数值
// Input: type :
// Output:
//------------------------------------------------------------
void pid_setinteg(PIDFollowCtrl_Struct *pid,float new_integ)
{
pid->integral = new_integ;
pid->last_error = 0;
}
//-----------------------------------------------------------------------------
// Subroute Name: pid_bumpless
// Create Time: 06.11.7
// Ver: 0.99
// Author: YSF
// Description: 伪PID突然设定了一个新的数值或者PID调整长期停止,这个等式将产生一个
// 尖峰输出,这个功能将能消除这个尖峰,处理数值PV将被校正正确,这个函数被应用后
// Input: type :
// Output:
//------------------------------------------------------------
void pid_bumpless(PIDFollowCtrl_Struct *pid)
{
pid->last_error = (pid->SP)-(pid->PV);
}
//-----------------------------------------------------------
// Subroute Name: pid_setinteg
// Create Time: 06.11.7
// Ver: 0.99
// Author: YSF
// Description: 执行PID计算,此过程是个反复过程
// Input: type :
// Output:
//------------------------------------------------------------
float pid_calc(PIDFollowCtrl_Struct *pid)
{
//unsigned int err;
int err;
float pterm, dterm, result, ferror;
err = (pid->SP) - (pid->PV);
//if(abs(err) > pid->deadband)
{
ferror = (float) err;
pterm = pid->pgain * ferror;
if (pterm > 1 || pterm < -1)
{
pid->integral = 0;
}
else
{
pid->integral += pid->igain * ferror;
if(pid->integral > 1.0)
{
pid->integral = 1.0;
}else if(pid->integral < 0.0)
{
pid->integral = 0.0;
}
}
dterm = ((float)(err - pid->last_error)) * pid->dgain; result = pterm + pid->integral + dterm;
}
/*else
{
result = pid->integral;
}*/
pid->last_error = err;
return (result);
}
百度搜索“爱华网”,专业资料,生活学习,尽在爱华网