《2022年模糊PID控制温控系统设计方案C语言程序代码 .pdf》由会员分享,可在线阅读,更多相关《2022年模糊PID控制温控系统设计方案C语言程序代码 .pdf(18页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、/* 模糊 PID 控制温控系统仿真设计C 程序代码*/ #include #define uchar unsigned char #define uint unsigned int #define PULSE 200 #define number 0.035 sbit SDO = P20。sbit SDI = P21。sbit CS = P22 。sbit CLK = P23。sbit EOC = P24。sbit RS = P25 。sbit RW = P26。sbit EN = P27。sbit KEY1= P30。sbit KEY2= P31。sbit KEY3= P32。sbit K
2、EY4= P33。sbit KEY5= P34。sbit IN1 = P35。sbit IN2 = P36。sbit ENA = P37。uchar flag。uchar flag_start 。float S_temp=60.0。float P_temp=20.0。float Kp。float Ki 。float Kd。float Err=0.0。float Last_Err=0.0。float D_Err=0.0。float Sum_Err=0.0。float U=0.0。/* 函数功能:延时*/ void delay_ms(uchar z) 精选学习资料 - - - - - - - -
3、- 名师归纳总结 - - - - - - -第 1 页,共 18 页 uchar i。 uchar j。 for(i=z。i0。i-) for(j=360。j0。j-)。 void delay_us(uchar z) uchar i。 for(i=z。i0。i-)。 void LCD_WriteData(uchar Dat) RS = 1。 P1 = Dat。 delay_us(10) 。 EN = 1。 delay_us(10) 。 EN = 0。 void LCD_WriteCOM(uchar com) RS = 0。 P1 = com。 delay_us(10) 。 EN = 1。 de
4、lay_us(10) 。 EN = 0。 void Show_Num(uchar x,uchar y,uchar n,float num) uchar a3。 uchar i。 uint Temp。 Temp=(int)num。 for(i=0。i0。i-) LCD_WriteData(ai-1+0 x30) 。 void Show_Ki(uchar num_Ki) uchar Temp 。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) 。Tem
5、p=Temp/10 。Show_Num(7,2,1,Temp) 。 void Show_char(uchar x,uchar y,uchar ch) if(y%2 = 1) LCD_WriteCOM(0 x80+x) 。 else LCD_WriteCOM(0 x80+0 x40+x) 。 LCD_WriteData(ch)。 void LCD_Init(void) RW = 0。 EN = 0。 LCD_WriteCOM(0 x38) 。 LCD_WriteCOM(0 x0c) 。 LCD_WriteCOM(0 x06) 。 LCD_WriteCOM(0 x01) 。 /* 函数功能:显示函
6、数*/ void LCD_display(void) Show_char(1,1,T) 。 delay_us(10) 。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 3 页,共 18 页 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_
7、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
8、_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 初始化*/ void Timer2_Init() RCAP2H =(65536-300)/256。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 4 页,共 18 页 RCAP2L =(65536-300)%256。 TH2 = RCAP
9、2H。 TL2 = RCAP2L。 ET2 = 1。 TR2 = 1。 EA = 1。 /* 函数功能:键盘扫描,调整设置温度*/ void key_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_temp0) S_temp=S_temp-1 。else if(S_temp=0) S_temp=0。while(!KEY2) 。 if(KEY3=0) delay_
10、ms(1)。if(KEY3=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 的计算*/ void PID_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=2
11、00) U=200。flag=1。 else U=-U。if(U=200) U=200。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 6 页,共 18 页flag=0。 /* 函数功能: PID 参数 Kp 的计算*/ float fuzzy_kp(float e, float ec) /e,ec,表示误差,误差变化率 float Kp_calcu。uchar num,pe,pec 。float code eRule7=-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0。 /误差 E的模糊论域float code ecRule7=-3.
12、0,-2.0,-1.0,0.0,1.0,2.0,3.0。 /误差变化率 EC 的模糊论域float eFuzzy2=0.0,0.0 。 /隶属于误差E 的隶属程度float ecFuzzy2=0.0,0.0 。 /隶属于误差变化率EC 的隶属程度float code kpRule4=0.0,8.0,16.0,24.0。/Kp 的模糊子集float KpFuzzy4=0.0,0.0,0.0,0.0 。/ 隶 属 于Kp 的隶属程度int code KpRule77= /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
13、,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(eeRule0) eFuzzy0 =1.0。pe = 0。 else if(eRule0=e & eeRule1) eFuzzy0 = (eRule1-e)/(eRule1-eRule0)。pe = 0。 else if(eRule1=e & eeRule2) 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 7 页,共 18 页 eFuzzy0 = (eRule2 -e)/(eRule2-eRule1)。p
14、e = 1。 else if(eRule2=e & eeRule3) eFuzzy0 = (eRule3 -e)/(eRule3-eRule2)。pe = 2。 else if(eRule3=e & eeRule4) eFuzzy0 = (eRule4-e)/(eRule4-eRule3) 。 pe = 3。 else if(eRule4=e & eeRule5) eFuzzy0 = (eRule5-e)/(eRule5-eRule4)。pe = 4。 else if(eRule5=e & eeRule6) eFuzzy0 = (eRule6-e)/(eRule6-eRule5)。pe = 5
15、。 else eFuzzy0 =0.0。pe =5。 eFuzzy1 =1.0 - eFuzzy0。/* 误差变化率 EC 隶属函数描述 */ if(ececRule0) ecFuzzy0 =1.0。pec = 0。 else if(ecRule0=ec & ececRule1) ecFuzzy0 = (ecRule1 - ec)/(ecRule1-ecRule0)。pec = 0 。 else if(ecRule1=ec & ececRule2) ecFuzzy0 = (ecRule2 - ec)/(ecRule2-ecRule1)。pec = 1。精选学习资料 - - - - - - -
16、- - 名师归纳总结 - - - - - - -第 8 页,共 18 页 else if(ecRule2=ec & ececRule3) ecFuzzy0 = (ecRule3 - ec)/(ecRule3-ecRule2)。pec = 2 。 else if(ecRule3=ec & ececRule4) ecFuzzy0 = (ecRule4-ec)/(ecRule4-ecRule3)。 pec=3 。 else if(ecRule4=ec & ececRule5) ecFuzzy0 = (ecRule5-ec)/(ecRule5-ecRule4)。 pec=4 。 else if(ecR
17、ule5=ec & ececRule6) ecFuzzy0 = (ecRule6-ec)/(ecRule6-ecRule5)。 pec=5 。 else ecFuzzy0 =0.0。pec = 5。 ecFuzzy1 = 1.0 - ecFuzzy0。/*查询模糊规则表 */ num =KpRulepepec。KpFuzzynum += eFuzzy0*ecFuzzy0 。num =KpRulepepec+1。KpFuzzynum += eFuzzy0*ecFuzzy1 。num =KpRulepe+1pec。KpFuzzynum += eFuzzy1*ecFuzzy0 。num =KpRul
18、epe+1pec+1。KpFuzzynum += eFuzzy1*ecFuzzy1 。/*加权平均法解模糊*/ Kp_calcu=KpFuzzy0*kpRule0+KpFuzzy1*kpRule1+KpFuzzy2*kpRule2 +KpFuzzy3*kpRule3 。return(Kp_calcu)。 /* 函数功能: PID 参数 Ki 的计算*/ float fuzzy_ki(float e, float ec) 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 9 页,共 18 页float Ki_calcu。uchar num,pe,pec
19、 。float code eRule7=-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0。float code ecRule7=-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0。float eFuzzy2=0.0,0.0 。float ecFuzzy2=0.0,0.0 。float code kiRule4=0.00,0.01,0.02,0.03 。float KiFuzzy4=0.0,0.0,0.0,0.0 。int code KiRule77= 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
20、,0,0,0,0,0,0, 2,0,0,0,0,0,1, 3,3,3,3,3,3,3 。 /* 误差隶属函数描述 */ if(eeRule0) eFuzzy0 =1.0。pe = 0。 else if(eRule0=e & eeRule1) eFuzzy0 = (eRule1-e)/(eRule1-eRule0)。pe = 0。 else if(eRule1=e & eeRule2) eFuzzy0 = (eRule2 -e)/(eRule2-eRule1)。pe = 1。 else if(eRule2=e & eeRule3) eFuzzy0 = (eRule3 -e)/(eRule3-eR
21、ule2)。pe = 2。 else if(eRule3=e & eeRule4) eFuzzy0 = (eRule4-e)/(eRule4-eRule3) 。 pe = 3。 else if(eRule4=e & eeRule5) 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 10 页,共 18 页 eFuzzy0 = (eRule5-e)/(eRule5-eRule4)。pe = 4。 else if(eRule5=e & eeRule6) eFuzzy0 = (eRule6-e)/(eRule6-eRule5)。pe = 5。 else e
22、Fuzzy0 =0.0。pe =5。 eFuzzy1 =1.0 - eFuzzy0。/* 误差变化隶属函数描述 */ if(ececRule0) ecFuzzy0 =1.0。pec = 0。 else if(ecRule0=ec & ececRule1) ecFuzzy0 = (ecRule1 - ec)/(ecRule1-ecRule0)。pec = 0 。 else if(ecRule1=ec & ececRule2) ecFuzzy0 = (ecRule2 - ec)/(ecRule2-ecRule1)。pec = 1。 else if(ecRule2=ec & ececRule3) e
23、cFuzzy0 = (ecRule3 - ec)/(ecRule3-ecRule2)。pec = 2 。 else if(ecRule3=ec & ececRule4) ecFuzzy0 = (ecRule4-ec)/(ecRule4-ecRule3)。 pec=3 。 else if(ecRule4=ec & ececRule5) ecFuzzy0 = (ecRule5-ec)/(ecRule5-ecRule4)。 pec=4 。 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 11 页,共 18 页else if(ecRule5=ec & ec
24、ecRule6) ecFuzzy0 = (ecRule6-ec)/(ecRule6-ecRule5)。 pec=5 。 else ecFuzzy0 =0.0。pec = 5。 ecFuzzy1 = 1.0 - ecFuzzy0。/*查询模糊规则表 */ num =KiRulepepec。KiFuzzynum += eFuzzy0*ecFuzzy0 。num =KiRulepepec+1 。KiFuzzynum += eFuzzy0*ecFuzzy1 。num =KiRulepe+1pec 。KiFuzzynum += eFuzzy1*ecFuzzy0 。num =KiRulepe+1pec+1
25、 。KiFuzzynum += eFuzzy1*ecFuzzy1 。/*加权平均法解模糊*/ Ki_calcu=KiFuzzy0*kiRule0+KiFuzzy1*kiRule1+KiFuzzy2*kiRule2 +KiFuzzy3*kiRule3 。 return(Ki_calcu)。 /* 函数功能: PID 参数 Kd 的计算*/ float fuzzy_kd(float e, float ec) float Kd_calcu。uchar num,pe,pec 。float code eRule7=-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0。float code ecR
26、ule7=-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0。float eFuzzy2=0.0,0.0 。float ecFuzzy2=0.0,0.0 。float code kdRule4=0.0,1.0,2.0,3.0。float KdFuzzy4=0.0,0.0,0.0,0.0 。int code KdRule77= 3,3,3,2,2,2,2, 2,2,2,1,1,1,1, 1,1,2,1,1,2,1, 1,1,0,1,0,1,1, 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 12 页,共 18 页1,1,0,0,0,1,1
27、, 2,2,1,0 ,1,1,1, 3,3,3,3,2,3,2 。 /* 误差隶属函数描述 */ if(eeRule0) eFuzzy0 =1.0。pe = 0。 else if(eRule0=e & eeRule1) eFuzzy0 = (eRule1-e)/(eRule1-eRule0)。pe = 0。 else if(eRule1=e & eeRule2) eFuzzy0 = (eRule2 -e)/(eRule2-eRule1)。pe = 1。 else if(eRule2=e & eeRule3) eFuzzy0 = (eRule3 -e)/(eRule3-eRule2)。pe =
28、2。 else if(eRule3=e & eeRule4) eFuzzy0 = (eRule4-e)/(eRule4-eRule3) 。 pe = 3。 else if(eRule4=e & eeRule5) eFuzzy0 = (eRule5-e)/(eRule5-eRule4)。pe = 4。 else if(eRule5=e & eeRule6) eFuzzy0 = (eRule6-e)/(eRule6-eRule5)。pe = 5。 else eFuzzy0 =0.0。pe =5。 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 13 页
29、,共 18 页 eFuzzy1 =1.0 - eFuzzy0。/* 误差变化隶属函数描述 */ if(ececRule0) ecFuzzy0 =1.0。pec = 0。 else if(ecRule0=ec & ececRule1) ecFuzzy0 = (ecRule1 - ec)/(ecRule1-ecRule0)。pec = 0 。 else if(ecRule1=ec & ececRule2) ecFuzzy0 = (ecRule2 - ec)/(ecRule2-ecRule1)。pec = 1。 else if(ecRule2=ec & ececRule3) ecFuzzy0 = (
30、ecRule3 - ec)/(ecRule3-ecRule2)。pec = 2 。 else if(ecRule3=ec & ececRule4) ecFuzzy0 = (ecRule4-ec)/(ecRule4-ecRule3)。 pec=3 。 else if(ecRule4=ec & ececRule5) ecFuzzy0 = (ecRule5-ec)/(ecRule5-ecRule4)。 pec=4 。 else if(ecRule5=ec & ececRule6) ecFuzzy0 = (ecRule6-ec)/(ecRule6-ecRule5)。 pec=5 。 else ecFu
31、zzy0 =0.0。pec = 5。 ecFuzzy1 = 1.0 - ecFuzzy0。/*查询模糊规则表 */ num =KdRulepepec。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 14 页,共 18 页KdFuzzynum += eFuzzy0*ecFuzzy0 。num =KdRulepepec+1。KdFuzzynum += eFuzzy0*ecFuzzy1 。num =KdRulepe+1pec。KdFuzzynum += eFuzzy1*ecFuzzy0 。num =KdRulepe+1pec+1。KdFuzzynum +
32、= eFuzzy1*ecFuzzy1 。/*加权平均法解模糊 */ Kd_calcu=KdFuzzy0*kdRule0+KdFuzzy1*kdRule1+KdFuzzy2*kdRule2 +KdFuzzy3*kdRule3 。 return(Kd_calcu)。 /* 函数功能: AD 将采集到的温度进行转化*/ uint read_tlc2543(uchar port) static uchar PORT = 0 。 uchar Temp,i,k=0。 uint AD_value=0。 Temp = port。 CS = 1。 CLK = 0。 Temp=4。 CS = 0。 while(1
33、) for(i=0。i8。i+) CLK = 0。 if(Temp&0 x80) SDI = 1。 else SDI = 0。AD_value=1。 if(SDO) AD_value |= 0 x01。 CLK = 1。 Temp=1。 for(i=8。i12。i+) 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 15 页,共 18 页 CLK = 0。 AD_value=1。 if(SDO) AD_value |= 0 x01。 delay_us(10) 。 CLK = 1。 CLK = 0。 CS = 1。 if(PORT = port) b
34、reak 。 else Temp = port 。 Temp2) PORT = port。 return AD_value。 float AD_deal(void) uint AD_value。 float temp。 AD_value = read_tlc2543(0 x00) 。 temp = AD_value*number。 return temp 。 /*主函数 */ void main(void) uchar AD_value=0。 flag=0。 flag_start=0。 ENA=1。 IN1=0。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - -
35、 - -第 16 页,共 18 页 IN2=0。 LCD_Init() 。 LCD_display()。 Timer2_Init()。 while(1) if(flag_start=0) key_scan() 。Show_Num(13,1,3,S_temp) 。Show_Num(3,1,3,P_temp) 。 else if(flag_start=1) P_temp=AD_deal()。Show_Num(3,1,3,P_temp) 。PID_Calculate()。Kp=fuzzy_kp(Err/5,D_Err) 。 /E量化因子 5 Ki=fuzzy_ki(Err/5,D_Err) 。Kd=fuzzy_kd(Err/5,D_Err) 。Show_Num(2,2,2,Kp)。Show_Ki(Ki) 。Show_Num(14,2,2,Kd)。key_scan() 。Show_Num(13,1,3,S_temp) 。 /*定时器 2 中断*/ void timer2() interrupt 5 static uchar num1=0 。 TF2 = 0。 num1+。 if(num1PULSE) num1=0。ENA=1。 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 18 页,共 18 页