模糊PID控制温控系统设计C语言程序代码汇总文档格式.docx
《模糊PID控制温控系统设计C语言程序代码汇总文档格式.docx》由会员分享,可在线阅读,更多相关《模糊PID控制温控系统设计C语言程序代码汇总文档格式.docx(29页珍藏版)》请在冰豆网上搜索。
![模糊PID控制温控系统设计C语言程序代码汇总文档格式.docx](https://file1.bdocx.com/fileroot1/2023-2/3/f9d981ce-ab1d-426b-85c9-192a2b9c8dc3/f9d981ce-ab1d-426b-85c9-192a2b9c8dc31.gif)
floatP_temp=20.0;
floatKp;
floatKi;
floatKd;
floatErr=0.0;
floatLast_Err=0.0;
floatD_Err=0.0;
floatSum_Err=0.0;
floatU=0.0;
/******************************
函数功能:
延时
******************************/
voiddelay_ms(ucharz)
{
uchari;
ucharj;
for(i=z;
i>
0;
i--)
for(j=360;
j>
j--);
}
voiddelay_us(ucharz)
i--);
voidLCD_WriteData(ucharDat)
RS=1;
P1=Dat;
delay_us(10);
EN=1;
EN=0;
voidLCD_WriteCOM(ucharcom)
RS=0;
P1=com;
voidShow_Num(ucharx,uchary,ucharn,floatnum)
uchara[3];
uintTemp;
Temp=(int)num;
for(i=0;
i<
n;
i++)
{
a[i]=Temp%10;
Temp=Temp/10;
}
if(y%2==1)
LCD_WriteCOM(0x80+x);
else
LCD_WriteCOM(0x80+0x40+x);
for(i=n;
LCD_WriteData(a[i-1]+0x30);
voidShow_Ki(ucharnum_Ki)
{
ucharTemp;
num_Ki=Ki*100;
Temp=(uchar)num_Ki;
Show_Num(10,2,1,Temp%10);
Temp=Temp/10;
Show_Num(9,2,1,Temp%10);
Show_Num(7,2,1,Temp);
voidShow_char(ucharx,uchary,ucharch)
LCD_WriteData(ch);
voidLCD_Init(void)
RW=0;
LCD_WriteCOM(0x38);
LCD_WriteCOM(0x0c);
LCD_WriteCOM(0x06);
LCD_WriteCOM(0x01);
/***********************************
显示函数
*************************************/
voidLCD_display(void)
Show_char(1,1,'
T'
);
Show_char(0,1,'
P'
Show_char(2,1,'
:
'
Show_Num(3,1,3,P_temp);
Show_char(10,1,'
S'
Show_char(11,1,'
Show_char(12,1,'
Show_Num(13,1,3,S_temp);
Show_char(0,2,'
Show_char(1,2,'
Show_Num(2,2,2,Kp);
Show_char(5,2,'
I'
Show_char(6,2,'
Show_char(8,2,'
.'
Show_Ki(Ki);
Show_char(12,2,'
D'
Show_char(13,2,'
Show_Num(14,2,2,Kd);
/************************************
定时器2初始化
voidTimer2_Init()
RCAP2H=(65536-300)/256;
RCAP2L=(65536-300)%256;
TH2=RCAP2H;
TL2=RCAP2L;
ET2=1;
TR2=1;
EA=1;
/*************************************
键盘扫描,调整设置温度
****************************************/
voidkey_scan(void)
if(KEY1==0)
delay_ms
(1);
if(KEY1==0)
{
S_temp=S_temp+1;
if(S_temp>
=200)
S_temp=200;
while(!
KEY1);
}
if(KEY2==0)
if(KEY2==0)
0)
S_temp=S_temp-1;
elseif(S_temp<
=0)
S_temp=0;
KEY2);
}
if(KEY3==0)
if(KEY3==0)
if(S_temp<
=190)
S_temp=S_temp+10;
KEY3);
}
if(KEY4==0)
{
if(KEY4==0)
=10)
S_temp=S_temp-10;
KEY4);
if(KEY5==0)
if(KEY5==0)
flag_start=1;
KEY5);
PID的计算
**********************************/
voidPID_Calculate()
{
Err=S_temp-P_temp;
Sum_Err+=Err;
D_Err=Err-Last_Err;
Last_Err=Err;
U=Kp*Err+Ki*Sum_Err+Kd*D_Err;
U=(int)U;
if(U>
if(U>
U=200;
flag=1;
}
U=-U;
flag=0;
}
/***********************************************
PID参数Kp的计算
************************************************/
floatfuzzy_kp(floate,floatec)//e,ec,表示误差,误差变化率
{
floatKp_calcu;
ucharnum,pe,pec;
floatcodeeRule[7]={-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0};
//误差E的模糊论域
floatcodeecRule[7]={-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0};
//误差变化率EC的模糊论域
floateFuzzy[2]={0.0,0.0};
//隶属于误差E的隶属程度
floatecFuzzy[2]={0.0,0.0};
//隶属于误差变化率EC的隶属程度
floatcodekpRule[4]={0.0,8.0,16.0,24.0};
//Kp的模糊子集
floatKpFuzzy[4]={0.0,0.0,0.0,0.0};
//隶属于Kp的隶属程度
intcodeKpRule[7][7]=//Kp的模糊控制表
3,3,3,3,3,3,3,
2,2,2,2,1,2,2,
1,1,1,1,1,1,1,
1,1,0,1,0,1,1,
0,0,1,0,0,1,0,
0,1,0,1,0,0,2,
3,3,3,3,3,3,3
};
/*****误差E隶属函数描述*****/
if(e<
eRule[0])
eFuzzy[0]=1.0;
pe=0;
elseif(eRule[0]<
=e&
&
e<
eRule[1])
eFuzzy[0]=(eRule[1]-e)/(eRule[1]-eRule[0]);
elseif(eRule[1]<
eRule[2])
eFuzzy[0]=(eRule[2]-e)/(eRule[2]-eRule[1]);
pe=1;
elseif(eRule[2]<
eRule[3])
eFuzzy[0]=(eRule[3]-e)/(eRule[3]-eRule[2]);
pe=2;
elseif(eRule[3]<
eRule[4])
{eFuzzy[0]=(eRule[4]-e)/(eRule[4]-eRule[3]);
pe=3;
elseif(eRule[4]<
eRule[5])
eFuzzy[0]=(eRule[5]-e)/(eRule[5]-eRule[4]);
pe=4;
elseif(eRule[5]<
eRule[6])
eFuzzy[0]=(eRule[6]-e)/(eRule[6]-eRule[5]);
pe=5;
eFuzzy[0]=0.0;
pe=5;
eFuzzy[1]=1.0-eFuzzy[0];
/*****误差变化率EC隶属函数描述*****/
if(ec<
ecRule[0])
ecFuzzy[0]=1.0;
pec=0;
elseif(ecRule[0]<
=ec&
ec<
ecRule[1])
ecFuzzy[0]=(ecRule[1]-ec)/(ecRule[1]-ecRule[0]);
pec=0;
elseif(ecRule[1]<
ecRule[2])
ecFuzzy[0]=(ecRule[2]-ec)/(ecRule[2]-ecRule[1]);
pec=1;
elseif(ecRule[2]<
ecRule[3])
ecFuzzy[0]=(ecRule[3]-ec)/(ecRule[3]-ecRule[2]);
pec=2;
elseif(ecRule[3]<
ecRule[4])
{ecFuzzy[0]=(ecRule[4]-ec)/(ecRule[4]-ecRule[3]);
pec=3;
elseif(ecRule[4]<
ecRule[5])
{ecFuzzy[0]=(ecRule[5]-ec)/(ecRule[5]-ecRule[4]);
pec=4;
elseif(ecRule[5]<
ecRule[6])
{ecFuzzy[0]=(ecRule[6]-ec)/(ecRule[6]-ecRule[5]);
pec=5;
ecFuzzy[0]=0.0;
pec=5;
ecFuzzy[1]=1.0-ecFuzzy[0];
/*********查询模糊规则表*********/
num=KpRule[pe][pec];
KpFuzzy[num]+=eFuzzy[0]*ecFuzzy[0];
num=KpRule[pe][pec+1];
KpFuzzy[num]+=eFuzzy[0]*ecFuzzy[1];
num=KpRule[pe+1][pec];
KpFuzzy[num]+=eFuzzy[1]*ecFuzzy[0];
num=KpRule[pe+1][pec+1];
KpFuzzy[num]+=eFuzzy[1]*ecFuzzy[1];
/*********加权平均法解模糊*********/Kp_calcu=KpFuzzy[0]*kpRule[0]+KpFuzzy[1]*kpRule[1]+KpFuzzy[2]*kpRule[2]
+KpFuzzy[3]*kpRule[3];
return(Kp_calcu);
PID参数Ki的计算
floatfuzzy_ki(floate,floatec)
floatKi_calcu;
floatcodekiRule[4]={0.00,0.01,0.02,0.03};
floatKiFuzzy[4]={0.0,0.0,0.0,0.0};
intcodeKiRule[7][7]=
0,0,0,0,0,0,0,
2,0,0,0,0,0,1,
/*****误差隶属函数描述*****/
if(e<
/*****误差变化隶属函数描述*****/
/***********查询模糊规则表***************/
num=KiRule[pe][pec];
KiFuzzy[num]+=eFuzzy[0]*ecFuzzy[0];
num=KiRule[pe][pec+1];
KiFuzzy[num]+=eFuzzy[0]*ecFuzzy[1];
num=KiRule[pe+1][pec];
KiFuzzy[num]+=eFuzzy[1]*ecFuzzy[0];
num=KiRule[pe+1][pec+1];
KiFuzzy[num]+=eFuzzy[1]*ecFuzzy[1];
/********加权平均法解模糊********/Ki_calcu=KiFuzzy[0]*kiRule[0]+KiFuzzy[1]*kiRule[1]+KiFuzzy[2]*kiRule[2]
+KiFuzzy[3]*kiRule[3];
return(Ki_calcu);
/*