你很幸运!我正在做老师留的作业,就是这个题。
PID调试一般原则 :
a.在输出不振荡时,增大比例增益P。
b.在输出不振荡时,减小积分时间常数Ti。
c.在输出不振荡时,增大微分时间常数Td。
调整方法:
工程整定法
经验法
凑试法
整定的步骤主要是先比例、再积分最后微分。
对于数字式PID调节应首先确定采样周期。从理论上讲,采样频率越高,失真越小。但是,对于控制器,由于是依靠偏差信号来进行调节计算的,当采样周期T太小,偏差信号也会过小,此时计算机将失去调节作用;若采样周期T太长,则将引起误差。因此采样周期T必须综合考虑。然后确定Kp,Ti,Td常用的有扩充临界比例度法和扩充响应曲线法。
参数整定找最佳,从小到大顺序查
先是比例后积分,最后再把微分加
曲线振荡很频繁,比例度盘要放大
曲线漂浮绕大湾,比例度盘往小扳
曲线偏离回复慢,积分时间往下降
曲线波动周期长,积分时间再加长
曲线振荡频率快,先把微分降下来
动差大来波动慢。微分时间应加长
理想曲线两个波,前高后低4比1
一看二调多分析,调节质量不会低
PID控制算法程序采用结构体定义:
struct PID{
unsigned int SetPoint; //设定目标Desired Value
double Proportion; //比例常数Proportional Const
double Integral; //积分常数Integral Const
double Derivative; //微分常数Derivative Const
unsigned int LastError; //Error[-1]
unsigned int PrevError; //Error[-2]
unsigned int SumError; //Sums of Errors
}spid;
在PID控制算法中,经过不断与给定值进行比较,动态控制电压电流输出的稳定,同时确保电压电流输出的精度。
PID控制算法程序如下:
unsigned int PIDCalc(struct PID *pp,unsigned int Next-Point)
{
unsigned int dError,Error;
Error=pp->SetPoint-NextPoint; //偏差
pp->SumError+= Error; //积分
dError=pp->LastError-pp->PrevError; //当前微分
pp->PrevError=pp->LastError;
pp->LastError= Error;
return(pp->Proportion* Error //比例
+pp->Integral*pp->SumError //积分项
+pp->Derivative*dError); //微分项
}
增量式PID算法
typedef struct PID {
int SetPoint; //设定目标 Desired Value
long SumError; //误差累计
double Proportion; //比例常数 Proportional Const
double Integral; //积分常数 Integral Const
double Derivative; //微分常数 Derivative Const
int LastError; //Error[-1]
int PrevError; //Error[-2] } PID;
include”DSP28x_Project.h”
include”main.h”
typedef struct PIDValue
{
double Ek_double[3]; //差值保存,给定值与反馈值的差值 RK-CK
double KP_double;
double KI_double;
double KD_double;
double Uk_double; //输出高度
double RK_double; //设定值
double CK_double; //反馈值
}PIDValueStr;
PIDValueStr PID;
void PIDOperation (void)
{
int16 Temp[3]; //临时变量
int16 PostSum; // U(K)
int i;
//Temp[0] = 0;
//Temp[1] = 0;
//Temp[2] = 0;
PostSum = 0;
Temp[0] = PID.RK_double- PID.CK_double; //差值数移
PID.Ek_double[2] = PID.Ek_double[1];
PID.Ek_double[1] = PID.Ek_double[0];
PID.Ek_double[0] = Temp[0];
Temp[0]=PID.Ek_double[0] - PID.Ek_double[1]; // E(K)
Temp[2]=PID.Ek_double[1]*2 ;
Temp[2]=(PID.Ek_double[0]+ PID.Ek_double[2])-Temp[2]; //E(k-2)+E(k)-2E(k-1)
Temp[0] = PID.KP_double * Temp[0]; // KP*[E(k)-E(k-1)]
Temp[1] = PID.KI_double * PID.Ek_double[0]; // KI*E(k)
Temp[2] = PID.KD_double * Temp[2]; // KD*[E(k-2)+E(k)-2E(k-1)]
for (i=0;i<3;i++)
PostSum += Temp[i];
PID.UK_double+= PostSum;
if( PID.UK_double/10>260)
PID.UK_double=2600;
else if(PID.UK_double/10<110)
PID.UK_double=1100;
}