PID公式:
Ti,Td分别为积分,微分常数,只取PI部分:
根据采样周期T离散化,t=nT,用n表示,
可得增量式:
分别为比例,积分系数
A,B为计算系数
最终输出:
写代码时,定义一个结构体来存放各个参数,
程序设计流程为: 本次采样输入→计算本次误差→计算输出增量→更新数据为下次做准备
代码如下:
typedef struct
{
int SetValue; //设置值
int An; //当前误差e(n)的系数,=kp+ki
int Bn_1; //前一项误差e(n-1)的系数,= -kp
int Limit; //限制最大最小值
int Errorn_1; //e(n-1)
int DeltaUn; //输出增量△u(n);
int Un_output; //输出值 u(n)
}PI_Typedef;
void PI_StructInit(PI_Typedef *PI_Struct,int Kp,int Ki,int limit);
void PI_Controller(PI_Typedef *PI_Struct,int NewInput,int *Output);
void PI_StructInit(PI_Typedef *PI_Struct,int Kp,int Ki,int limit)
{
PI_Struct->SetValue = 0;
PI_Struct->An = Kp+Ki;
PI_Struct->Bn_1 = -Kp;
PI_Struct->Limit = limit;
PI_Struct->DeltaUn = 0;
PI_Struct->Errorn_1 = 0;
}
void PI_Controller(PI_Typedef *PI_Struct,int NewInput,int *Output)
{
int Errorn =0;
Errorn = PI_Struct->SetValue - NewInput;//计算e(n)
PI_Struct->DeltaUn = (PI_Struct->An)*Errorn+(PI_Struct->Bn_1)*(PI_Struct->Errorn_1);//计算增量
PI_Struct->Errorn_1 = Errorn;//保存误差e(n)作为下一次计算的e(n-1)
//限制增量的范围
if(PI_Struct->DeltaUn > PI_Struct->Limit)
{PI_Struct->DeltaUn = PI_Struct->Limit;}
else if(PI_Struct->DeltaUn < -PI_Struct->Limit)
{PI_Struct->DeltaUn = -PI_Struct->Limit;}
PI_Struct->Un_output += PI_Struct->DeltaUn; //计算输出u(n)=u(n-1)+△u(n),并保存作下一次运算
*Output = PI_Struct->Un_output;
}