模糊PID控制温控系统设计方案C语言程序代码.docx
《模糊PID控制温控系统设计方案C语言程序代码.docx》由会员分享,可在线阅读,更多相关《模糊PID控制温控系统设计方案C语言程序代码.docx(30页珍藏版)》请在冰豆网上搜索。
模糊PID控制温控系统设计方案C语言程序代码
/********************************************************************
模糊PID控制温控系统仿真设计C程序代码
********************************************************************/
#include
#defineucharunsignedchar
#defineuintunsignedint
#definePULSE200
#definenumber0.035
sbitSDO=P2^0。
sbitSDI=P2^1。
sbitCS=P2^2。
sbitCLK=P2^3。
sbitEOC=P2^4。
sbitRS=P2^5。
sbitRW=P2^6。
sbitEN=P2^7。
sbitKEY1=P3^0。
sbitKEY2=P3^1。
sbitKEY3=P3^2。
sbitKEY4=P3^3。
sbitKEY5=P3^4。
sbitIN1=P3^5。
sbitIN2=P3^6。
sbitENA=P3^7。
ucharflag。
ucharflag_start。
floatS_temp=60.0。
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>0。
j--)。
}
voiddelay_us(ucharz)
{
uchari。
for(i=z。
i>0。
i--)。
}
voidLCD_WriteData(ucharDat)
{
RS=1。
P1=Dat。
delay_us(10)。
EN=1。
delay_us(10)。
EN=0。
}
voidLCD_WriteCOM(ucharcom)
{
RS=0。
P1=com。
delay_us(10)。
EN=1。
delay_us(10)。
EN=0。
}
voidShow_Num(ucharx,uchary,ucharn,floatnum)
{
uchara[3]。
uchari。
uintTemp。
Temp=(int)num。
for(i=0。
ii++)
{
a[i]=Temp%10。
Temp=Temp/10。
}
if(y%2==1)
LCD_WriteCOM(0x80+x)。
else
LCD_WriteCOM(0x80+0x40+x)。
for(i=n。
i>0。
i--)
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)。
Temp=Temp/10。
Show_Num(7,2,1,Temp)。
}
voidShow_char(ucharx,uchary,ucharch)
{
if(y%2==1)
LCD_WriteCOM(0x80+x)。
else
LCD_WriteCOM(0x80+0x40+x)。
LCD_WriteData(ch)。
}
voidLCD_Init(void)
{
RW=0。
EN=0。
LCD_WriteCOM(0x38)。
LCD_WriteCOM(0x0c)。
LCD_WriteCOM(0x06)。
LCD_WriteCOM(0x01)。
}
/***********************************
函数功能:
显示函数
*************************************/
voidLCD_display(void)
{
Show_char(1,1,'T')。
delay_us(10)。
Show_char(0,1,'P')。
delay_us(10)。
Show_char(1,1,'T')。
delay_us(10)。
Show_char(2,1,':
')。
delay_us(10)。
Show_Num(3,1,3,P_temp)。
delay_us(10)。
Show_char(10,1,'S')。
delay_us(10)。
Show_char(11,1,'T')。
delay_us(10)。
Show_char(12,1,':
')。
delay_us(10)。
Show_Num(13,1,3,S_temp)。
delay_us(10)。
Show_char(0,2,'P')。
delay_us(10)。
Show_char(1,2,':
')。
delay_us(10)。
Show_Num(2,2,2,Kp)。
delay_us(10)。
Show_char(5,2,'I')。
delay_us(10)。
Show_char(6,2,':
')。
delay_us(10)。
Show_char(8,2,'.')。
delay_us(10)。
Show_Ki(Ki)。
delay_us(10)。
Show_char(12,2,'D')。
delay_us(10)。
Show_char(13,2,':
')。
delay_us(10)。
Show_Num(14,2,2,Kd)。
delay_us(10)。
}
/************************************
函数功能:
定时器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)
{
delay_ms
(1)。
if(KEY2==0)
{
if(S_temp>0)
S_temp=S_temp-1。
elseif(S_temp<=0)
S_temp=0。
while(!
KEY2)。
}
}
if(KEY3==0)
{
delay_ms
(1)。
if(KEY3==0)
{
if(S_temp<=190)
S_temp=S_temp+10。
while(!
KEY3)。
}
}
if(KEY4==0)
{
delay_ms
(1)。
if(KEY4==0)
{
if(S_temp>=10)
S_temp=S_temp-10。
while(!
KEY4)。
}
}
if(KEY5==0)
{
delay_ms
(1)。
if(KEY5==0)
{
flag_start=1。
while(!
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>=0)
{
if(U>=200)
U=200。
flag=1。
}
else
{
U=-U。
if(U>=200)
U=200。
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{
eFuzzy[0]=1.0。
pe=0。
}
elseif(eRule[0]<=e&&e{
eFuzzy[0]=(eRule[1]-e)/(eRule[1]-eRule[0])。
pe=0。
}
elseif(eRule[1]<=e&&e{
eFuzzy[0]=(eRule[2]-e)/(eRule[2]-eRule[1])。
pe=1。
}
elseif(eRule[2]<=e&&e{
eFuzzy[0]=(eRule[3]-e)/(eRule[3]-eRule[2])。
pe=2。
}
elseif(eRule[3]<=e&&e{eFuzzy[0]=(eRule[4]-e)/(eRule[4]-eRule[3])。
pe=3。
}
elseif(eRule[4]<=e&&e{
eFuzzy[0]=(eRule[5]-e)/(eRule[5]-eRule[4])。
pe=4。
}
elseif(eRule[5]<=e&&e{
eFuzzy[0]=(eRule[6]-e)/(eRule[6]-eRule[5])。
pe=5。
}
else
{
eFuzzy[0]=0.0。
pe=5。
}
eFuzzy[1]=1.0-eFuzzy[0]。
/*****误差变化率EC隶属函数描述*****/
if(ec{
ecFuzzy[0]=1.0。
pec=0。
}
elseif(ecRule[0]<=ec&&ec{
ecFuzzy[0]=(ecRule[1]-ec)/(ecRule[1]-ecRule[0])。
pec=0。
}
elseif(ecRule[1]<=ec&&ec{
ecFuzzy[0]=(ecRule[2]-ec)/(ecRule[2]-ecRule[1])。
pec=1。
}
elseif(ecRule[2]<=ec&&ec{
ecFuzzy[0]=(ecRule[3]-ec)/(ecRule[3]-ecRule[2])。
pec=2。
}
elseif(ecRule[3]<=ec&&ec{ecFuzzy[0]=(ecRule[4]-ec)/(ecRule[4]-ecRule[3])。
pec=3。
}
elseif(ecRule[4]<=ec&&ec{ecFuzzy[0]=(ecRule[5]-ec)/(ecRule[5]-ecRule[4])。
pec=4。
}
elseif(ecRule[5]<=ec&&ec{ecFuzzy[0]=(ecRule[6]-ec)/(ecRule[6]-ecRule[5])。
pec=5。
}
else
{
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。
ucharnum,pe,pec。
floatcodeeRule[7]={-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0}。
floatcodeecRule[7]={-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0}。
floateFuzzy[2]={0.0,0.0}。
floatecFuzzy[2]={0.0,0.0}。
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,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
2,0,0,0,0,0,1,
3,3,3,3,3,3,3
}。
/*****误差隶属函数描述*****/
if(e{
eFuzzy[0]=1.0。
pe=0。
}
elseif(eRule[0]<=e&&e{
eFuzzy[0]=(eRule[1]-e)/(eRule[1]-eRule[0])。
pe=0。
}
elseif(eRule[1]<=e&&e{
eFuzzy[0]=(eRule[2]-e)/(eRule[2]-eRule[1])。
pe=1。
}
elseif(eRule[2]<=e&&e{
eFuzzy[0]=(eRule[3]-e)/(eRule[3]-eRule[2])。
pe=2。
}
elseif(eRule[3]<=e&&e{eFuzzy[0]=(eRule[4]-e)/(eRule[4]-eRule[3])。
pe=3。
}
elseif(eRule[4]<=e&&e{
eFuzzy[0]=(eRule[5]-e)/(eRule[5]-eRule[4])。
pe=4。
}
elseif(eRule[5]<=e&&e{
eFuzzy[0]=(eRule[6]-e)/(eRule[6]-eRule[5])。
pe=5。
}
else
{
eFuzzy[0]=0.0。
pe=5。
}
eFuzzy[1]=1.0-eFuzzy[0]。
/*****误差变化隶属函数描述*****/
if(ec{
ecFuzzy[0]=1.0。
pec=0。
}
elseif(ecRule[0]<=ec&&ec{
ecFuzzy[0]=(ecRule[1]-ec)/(ecRule[1]-ecRule[0])。
pec=0。
}
elseif(ecRule[1]<=ec&&ec{
ecFuzzy[0]=(ecRule[2]-ec)/(ecRule[2]-ecRule[1])。
pec=1。
}
elseif(ecRule[2]<=ec&&ec{
ecFuzzy[0]=(ecRule[3]-ec)/(ecRule[3]-ecRule[2])。
pec=2。
}
elseif(ecRule[3]<=ec&&ec{ecFuzzy[0]=(ecRule[4]-ec)/(ecRule[4]-ecRule[3])。
pec=3。
}
elseif(ecRule[4]<=ec&&ec{ecFuzzy[0]=(ecRule[5]-ec)/(ecRule[5]-ecRule[4])。
pec=4。
}
elseif(ecRule[5]<=ec&&ec{ecFuzzy[0]=(ecRule[6]-ec)/(ecRule[6]-ecRule[5])。
pec=5。
}
else
{
ecFuzzy[0]=0.0。
pec=5。
}
ecFuzzy[1]=1.0-ecFuzzy[0]。
/***********查询模糊规则表***************/
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)。
}
/*