📄 pid.c
字号:
#include "config.h"
void PID(struct strPID * pidTab)
{
// 更新数据
pidTab->PidPara[PID_PdOld] = pidTab->PidPara[PID_PdNew];
// 偏差值
pidTab->PidPara[PID_PdNew] = pidTab->PidPara[PID_PvSet] - pidTab->PidPara[PID_PvNew];
// 积分项
if(pidTab->PidPara[PID_Ti] > 0)
{
if(pidTab->PidPara[PID_PdNew] < (0.5 * pidTab->PidPara[PID_P]) && pidTab->PidPara[PID_PdNew] > (-0.5 * pidTab->PidPara[PID_P]))
{
if(pidTab->PidPara[PID_Out] < 1 && pidTab->PidPara[PID_Out] > 0)
{
if((pidTab->PidPara[PID_PdNew] < pidTab->PidPara[PID_PdOld] && pidTab->PidPara[PID_PdNew] < 0 && pidTab->PidPara[PID_PdOld] < 0) ||
(pidTab->PidPara[PID_PdNew] > pidTab->PidPara[PID_PdOld] && pidTab->PidPara[PID_PdNew] > 0 && pidTab->PidPara[PID_PdOld] > 0))
{
// 偏差增大趋势
pidTab->PidPara[PID_Mi] = pidTab->PidPara[PID_Mi] + pidTab->PidPara[PID_PdNew] + 0.2 * pidTab->PidPara[PID_PdNew];
}
else if((pidTab->PidPara[PID_PdNew] > pidTab->PidPara[PID_PdOld] && pidTab->PidPara[PID_PdNew] < 0 && pidTab->PidPara[PID_PdOld] < 0) ||
(pidTab->PidPara[PID_PdNew] < pidTab->PidPara[PID_PdOld] && pidTab->PidPara[PID_PdNew] > 0 && pidTab->PidPara[PID_PdOld] > 0))
{
// 偏差减小趋势
pidTab->PidPara[PID_Mi] = pidTab->PidPara[PID_Mi] + 0.8 * pidTab->PidPara[PID_PdNew];
}
else
{
// 偏差在正负波动
pidTab->PidPara[PID_Mi] = pidTab->PidPara[PID_Mi] + 1.0 * pidTab->PidPara[PID_PdNew];
}
}
else if(pidTab->PidPara[PID_Out] == 1) // 积分正饱和
{
if(pidTab->PidPara[PID_PdNew] < 0) // 只处理负偏差
{
pidTab->PidPara[PID_Mi] = pidTab->PidPara[PID_Mi] + pidTab->PidPara[PID_PdNew];
}
}
else if(pidTab->PidPara[PID_Out] == 0) // 积分负饱和
{
if(pidTab->PidPara[PID_PdNew] > 0) // 只处理正偏差
{
pidTab->PidPara[PID_Mi] = pidTab->PidPara[PID_Mi] + pidTab->PidPara[PID_PdNew];
}
}
}
}
else
{
pidTab->PidPara[PID_Mi] = 0;
}
// 微分项
if(pidTab->PidPara[PID_Td] > 0)
{
if(pidTab->PidPara[PID_RUN_NUM] > 1) // 避免第一次计算时导致微分项很大
{
if(pidTab->PidPara[PID_PdNew] < (0.5 * pidTab->PidPara[PID_P])
&& pidTab->PidPara[PID_PdNew] > (-0.5 * pidTab->PidPara[PID_P])) // 在比例带范围内才进行微分项计算
{
//微分项低通滤波
pidTab->PidPara[PID_Md] = 0.6 * pidTab->PidPara[PID_Md]
+ 0.4 * pidTab->PidPara[PID_Td] * (pidTab->PidPara[PID_PdNew] - pidTab->PidPara[PID_PdOld]) / pidTab->PidPara[PID_Ts];
}
}
}
else
{
pidTab->PidPara[PID_Md] = 0;
}
// PID
if( pidTab->PidPara[PID_Ti] > 0) pidTab->PidPara[PID_Out] = pidTab->PidPara[PID_U] + pidTab->PidPara[PID_Kc] * (pidTab->PidPara[PID_PdNew] + pidTab->PidPara[PID_Ts] * pidTab->PidPara[PID_Mi] / pidTab->PidPara[PID_Ti] + pidTab->PidPara[PID_Md]);
else pidTab->PidPara[PID_Out] = pidTab->PidPara[PID_U] + pidTab->PidPara[PID_Kc] * (pidTab->PidPara[PID_PdNew] + pidTab->PidPara[PID_Md]);
// 合法输出
if(pidTab->PidPara[PID_Out] > 1.0) pidTab->PidPara[PID_Out] = 1;
else if(pidTab->PidPara[PID_Out] < 0.0) pidTab->PidPara[PID_Out] = 0;
// 统计PID执行次数
pidTab->PidPara[PID_RUN_NUM] = pidTab->PidPara[PID_RUN_NUM] + 1;
}//void PID(struct strPID pidTab)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -