|
double ref = 0; //設(shè)置參數(shù) 最大5V 對(duì)應(yīng)512 1V對(duì)應(yīng)102
double feb = 0; //采樣反饋 最大5V 對(duì)應(yīng)512 1V對(duì)應(yīng)102
int pwm_var = 0; //PID調(diào)整量
int PWM_out = 0; //PWM輸出量
int index =0 ;
int abs (int j); //絕對(duì)值函數(shù)定義
double Uo = 0;
double Ek = 0; //定義當(dāng)前偏差值
double Ek1 = 0; //定義上一次偏差值
double Ei = 0;
double Ed = 0;
#define Kp 0.4 //PID調(diào)節(jié)的比例常數(shù)
#define Ti 0.05 //PID調(diào)節(jié)的積分常數(shù)
#define Td 0.02 //PID調(diào)節(jié)的微分時(shí)間常數(shù)
#define T 0.02 //采樣周期
#define A 0
//原0.02 0.005 0
#define Kpp 0.15//0.02//0.05//0.02//0.04//0.08//Kp * ( 1 + (T / Ti) + (Td / T) ) // 0.96
#define Ki 0.04//0.01/*0.01*//*0.005*///*(-Kp) * ( 1 + (2 * Td / T ) ) // -1.2 //0.02-0.024// 0.016
#define Kd 0 //0.01//0.02//0//0.002//0.01///*0*/*Kp * Td / T //0.01對(duì)應(yīng)-0.004 // 0.4 //0.025-0.01//
#define N 10
#define uint8 char
#define Emin 10 //誤差的閥值即0.1V,避免誤差較小時(shí)頻繁調(diào)節(jié)引起震蕩
#define Umax 180//8//6//25//100 //調(diào)整值上限,防止積分飽和
#define Umin 10//-8//-6//-25//-100 //調(diào)整值下限,防止積分飽和
#define Pmax 300//200//84 //輸出值上限
#define Pmin -100//75//10 //輸出值下限
//----------------------PID執(zhí)行程序---------------------------------------------
//-----------------------PID試行 ----------------------------------------------
void pid_ctrl(void)
{ int index;
Ek = ref - feb; // 差值運(yùn)算 誤差=給定-反饋
if( (Ek <= Emin)&&(Ek >=-10) ) // 誤差的閥值小于10(即0.1V)
{
pwm_var = 0; // PID執(zhí)行增量等于0 不加減
}
if( feb>Pmax ) // 反饋值的閥值大于最大300 即3V
{
if(abs(Ek)>100) // 誤差絕對(duì)值大于100 即1V
{
index=0; //取消積分環(huán)節(jié)
}
else //否則
{
index=1; //加入積分環(huán)節(jié)
if(Ek>0) //如果反饋值>0
{
Ei+=Ek; //積分項(xiàng)累積負(fù)值
}
}
}
else if( feb<Pmin) //如果反饋值小于最小值-100 即-1V
{
if(abs(Ek)>80) //如果誤差絕對(duì)值>80 即0.8V
{
index=0; //取消積分環(huán)節(jié)
}
else //否則
{
index=1; //加入積分環(huán)節(jié)
if(Ek<0) //如果誤差值<0
{
Ei+=Ek; //累計(jì)負(fù)的積分值
}
}
}
else //否則
{
if(abs(Ek)>30) //如果誤差絕對(duì)值>200
{
index=0; //取消積分項(xiàng)
} else //否則
{
index=1; //加入積分項(xiàng)
Ei+=Ek; //累計(jì)積分值
}
}
Uo = Kpp*Ek + Ki*Ei*index + Kd*(Ek-Ek1); //PID增量計(jì)算
Ek1= Ek;
pwm_var = Uo*1.0;
PWM_out =PWM_out+pwm_var;
if(PWM_out > Umax ){PWM_out = Umax ; } //輸出值最大限幅512 約5V
if(PWM_out < Umin ){PWM_out = Umin ; } //輸出最小限制
CCAP1H=CCAP1L = 255- PWM_out; //輸出PWM暫空比 最大5V
}
|
|