/**********************************************************
******************
*
*文件名:FUZZY_PID.c
*
*功 能:此文件是模糊自适应整定 PID 控制程序
*
*作 者: Sahara
*
***********************************************************
*****************/
#include "DSP28_Device.h"
#include "stdlib.h"
#include "math.h"
#include "float.h" //浮点数处理
float error=0.0;//是指当前温度和目标温度之差
float Sumerror=0.0;//每次采样的温度差值之和
float Derror=0.0;//前后两次采样温差之差,就是所谓的温度变化率
float Lasterror=0.0;
float Preverror=0.0;
float Kp=1.0;//设置 PID 控制系数
float Ki=1.0;
float Kd=0.0;
float V_out=0.0;
/**********************************************************
******************
*
*文件名:PID_Calc(float error)
*
*功 能:此文件是 PID 计算子程序,此程序采用位置式方式,
* 增量式得到的是变化增量,最终的结果需要加修正值
* 增量式:
v(k)=V(k)-Vo(k-1)=Kp*[e(k)-e(k-1)]+Ki*e(k)+Kd*[e(k)-2e(k-1)+e(k-2)];
e(k)-e(k-1)=error;
e(k)=Sumerror;
e(k)-2e(k-1)+e(k-2)=[e(k)-e(k-1)]-[e(k-1)-e(k-2)]=Derror;
Lasterror=e(k-1)-e(k-2);
Derror=error-Lasterror;
*
* 位置式:
v(k)=Kp*e(k)+Ki*[e(k)+e(k-1)+e(k-2)+...]+Kd*[e(k)-e(k-1)];
e(k)=error;
e(k)+e(k-1)+e(k-2)+...=Sumerror;
e(k)-e(k-1)=Derror;
Lasterror=e(k-1);
Preverror=e(k-2);
Derror=error-Lasterror;
*作 者: Sahara
*
*入口参数:float error
*
*出口参数:V_out
*
***********************************************************
*****************/
void PID_Calc(float error)
{
Sumerror=Sumerror+error;
Derror=error-Lasterror;
Preverror=Lasterror;
Lasterror=error;
V_out=Kp*error+Ki*Sumerror+Kd*Derror;
//return(V_out);
}
/**********************************************************
******************
*
*文件名:FUZZY_Calc_Kp(float e,float ec)
*
*功 能:模糊算法 kp 计算部分
*
*作 者: Sahara
*
*入口参数:float e,float ec
*
*出口参数:Kp
*
***********************************************************
*****************/
void FUZZY_Calc_Kp(float e,float ec)
{
float eRule[7]={-3, -2, -1, 0, 1, 2, 3};
float ecRule[7]={-3, -2, -1, 0, 1, 2, 3};
float uRule[7]={-3, -2, -1, 0, 1, 2, 3};
float eFuzzy[7];
float eFuzzy_Out[6];
float ecFuzzy[7];
float ecFuzzy_Out[6];
float uFuzzy[7];
int Pe,Pec;
float Rule[7][7];
float a1, a2;//生成模糊规则表的可调因子
/*int Rule[6][6]={{3, 2, 2, 1, 0, 0},
{3, 2, 1, 1, 0, -1},
{2, 2, 1, 0, -1, -1},
{2, 1, 0, -1, -2, -2},
{1, 0, -1, -1, -2, -2},
{0, -1, -2, -2, -2, -3},
};
*/
/*int Rule[7][7]={{3, 3, 2, 2, 1, 0, 0},
{3, 3, 2, 1, 1, 0, -1},
{2, 2, 2, 1, 0, -1, -1},
{2, 2, 1, 0, -1, -2, -2},
{1, 1, 0, -1, -1, -2, -2},
{1, 0, -1, -2, -2, -2, -3},
{0, 0, -2, -2, -2, -3, -3},
};
*/
int i,j;
for(i=0;i<7;i++)
{
}
eFuzzy[i]=0;
for(i=0;i<7;i++)
{
}
ecFuzzy[i]=0;
for(i=0;i<7;i++)
{
}
uFuzzy[i]=0;
for(i=0;i<2;i++)
{
eFuzzy_Out[i]=0;
}
for(i=0;i<2;i++)
{
}
ecFuzzy_Out[i]=0;
/**********************************************************
******************
*
* 误差隶属函数描述
* 误差隶属函数的描述采用三角形隶属函数描述
*
***********************************************************
*****************/
if(e < eRule[0])
{
}
eFuzzy_Out[0] = 1.0;
Pe = 0;
else if(e > eRule[0] && e < eRule[1])
{
eFuzzy[0] = (e - eRule[1])/(eRule[0] - eRule[1]);
eFuzzy[1] = (e - eRule[0])/(eRule[1] - eRule[0]);
eFuzzy_Out[0] = eFuzzy[0] > eFuzzy[1] ? eFuzzy[0] : eFuzzy[1];
Pe = 0;
}
else if(e > eRule[1] && e < eRule[2])
{
}
eFuzzy[1] = (e - eRule[2])/(eRule[1] - eRule[2]);
eFuzzy[2] = (e - eRule[1])/(eRule[2] - eRule[1]);
eFuzzy_Out[1] = eFuzzy[1] > eFuzzy[2] ? eFuzzy[1] : eFuzzy[2];
Pe = 1;
else if(e > eRule[2] && e < eRule[3])
{
}
eFuzzy[2] = (e - eRule[3])/(eRule[2] - eRule[3]);
eFuzzy[3] = (e - eRule[2])/(eRule[3] - eRule[2]);
eFuzzy_Out[2] = eFuzzy[2] > eFuzzy[3] ? eFuzzy[2] : eFuzzy[3];
Pe = 2;
else if(e > eRule[3] && e < eRule[4])
{
eFuzzy[3] = (e - eRule[4])/(eRule[3] - eRule[4]);
eFuzzy[4] = (e - eRule[3])/(eRule[4] - eRule[3]);