收藏 分销(赏)

模糊PID控制温控系统设计C语言程序代码.doc

上传人:快乐****生活 文档编号:1795762 上传时间:2024-05-09 格式:DOC 页数:18 大小:98KB 下载积分:8 金币
下载 相关 举报
模糊PID控制温控系统设计C语言程序代码.doc_第1页
第1页 / 共18页
模糊PID控制温控系统设计C语言程序代码.doc_第2页
第2页 / 共18页


点击查看更多>>
资源描述
/******************************************************************** 模糊PID控制温控系统仿真设计C程序代码 ********************************************************************/ #include<reg52.h> #define uchar unsigned char #define uint unsigned int #define PULSE 200 #define number 0.035 sbit SDO = P2^0; sbit SDI = P2^1; sbit CS = P2^2; sbit CLK = P2^3; sbit EOC = P2^4; sbit RS = P2^5; sbit RW = P2^6; sbit EN = P2^7; sbit KEY1= P3^0; sbit KEY2= P3^1; sbit KEY3= P3^2; sbit KEY4= P3^3; sbit KEY5= P3^4; sbit IN1 = P3^5; sbit IN2 = P3^6; sbit ENA = P3^7; 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) { uchar i; uchar j; for(i=z;i>0;i--) for(j=360;j>0;j--); } void delay_us(uchar z) { uchar i; for(i=z;i>0;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; delay_us(10); EN = 0; } void Show_Num(uchar x,uchar y,uchar n,float num) { uchar a[3]; uchar i; uint Temp; 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;i>0;i--) LCD_WriteData(a[i-1]+0x30); } 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); Temp=Temp/10; Show_Num(7,2,1,Temp); } void Show_char(uchar x,uchar y,uchar ch) { if(y%2 == 1) LCD_WriteCOM(0x80+x); else LCD_WriteCOM(0x80+0x40+x); LCD_WriteData(ch); } void LCD_Init(void) { RW = 0; EN = 0; LCD_WriteCOM(0x38); LCD_WriteCOM(0x0c); LCD_WriteCOM(0x06); LCD_WriteCOM(0x01); } /*********************************** 函数功能:显示函数 *************************************/ void LCD_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初始化 *************************************/ void Timer2_Init() { RCAP2H =(65536-300)/256; RCAP2L =(65536-300)%256; TH2 = RCAP2H; 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_temp>0) S_temp=S_temp-1; else if(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的计算 **********************************/ 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>=200) U=200; flag=1; } else { U=-U; if(U>=200) U=200; flag=0; } } /*********************************************** 函数功能:PID参数Kp的计算 ************************************************/ float fuzzy_kp(float e, float ec) //e,ec,表示误差,误差变化率 { float Kp_calcu; uchar num,pe,pec; float code eRule[7]={-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0}; //误差E的模糊论域 float code ecRule[7]={-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0}; //误差变化率EC的模糊论域 float eFuzzy[2]={0.0,0.0}; //隶属于误差E的隶属程度 float ecFuzzy[2]={0.0,0.0}; //隶属于误差变化率EC的隶属程度 float code kpRule[4]={0.0,8.0,16.0,24.0}; //Kp的模糊子集 float KpFuzzy[4]={0.0,0.0,0.0,0.0}; //隶属于Kp的隶属程度 int code KpRule[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; } else if(eRule[0]<=e && e<eRule[1]) { eFuzzy[0] = (eRule[1]-e)/(eRule[1]-eRule[0]); pe = 0; } else if(eRule[1]<=e && e<eRule[2]) { eFuzzy[0] = (eRule[2] -e)/(eRule[2]-eRule[1]); pe = 1; } else if(eRule[2]<=e && e<eRule[3]) { eFuzzy[0] = (eRule[3] -e)/(eRule[3]-eRule[2]); pe = 2; } else if(eRule[3]<=e && e<eRule[4]) { eFuzzy[0] = (eRule[4]-e)/(eRule[4]-eRule[3]); pe = 3; } else if(eRule[4]<=e && e<eRule[5]) { eFuzzy[0] = (eRule[5]-e)/(eRule[5]-eRule[4]); pe = 4; } else if(eRule[5]<=e && e<eRule[6]) { 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<ecRule[0]) { ecFuzzy[0] =1.0; pec = 0; } else if(ecRule[0]<=ec && ec<ecRule[1]) { ecFuzzy[0] = (ecRule[1] - ec)/(ecRule[1]-ecRule[0]); pec = 0 ; } else if(ecRule[1]<=ec && ec<ecRule[2]) { ecFuzzy[0] = (ecRule[2] - ec)/(ecRule[2]-ecRule[1]); pec = 1; } else if(ecRule[2]<=ec && ec<ecRule[3]) { ecFuzzy[0] = (ecRule[3] - ec)/(ecRule[3]-ecRule[2]); pec = 2 ; } else if(ecRule[3]<=ec && ec<ecRule[4]) { ecFuzzy[0] = (ecRule[4]-ec)/(ecRule[4]-ecRule[3]); pec=3; } else if(ecRule[4]<=ec && ec<ecRule[5]) { ecFuzzy[0] = (ecRule[5]-ec)/(ecRule[5]-ecRule[4]); pec=4; } else if(ecRule[5]<=ec && ec<ecRule[6]) { 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的计算 ************************************************/ float fuzzy_ki(float e, float ec) { float Ki_calcu; uchar num,pe,pec; float code eRule[7]={-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0}; float code ecRule[7]={-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0}; float eFuzzy[2]={0.0,0.0}; float ecFuzzy[2]={0.0,0.0}; float code kiRule[4]={0.00,0.01,0.02,0.03}; float KiFuzzy[4]={0.0,0.0,0.0,0.0}; int code KiRule[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<eRule[0]) { eFuzzy[0] =1.0; pe = 0; } else if(eRule[0]<=e && e<eRule[1]) { eFuzzy[0] = (eRule[1]-e)/(eRule[1]-eRule[0]); pe = 0; } else if(eRule[1]<=e && e<eRule[2]) { eFuzzy[0] = (eRule[2] -e)/(eRule[2]-eRule[1]); pe = 1; } else if(eRule[2]<=e && e<eRule[3]) { eFuzzy[0] = (eRule[3] -e)/(eRule[3]-eRule[2]); pe = 2; } else if(eRule[3]<=e && e<eRule[4]) { eFuzzy[0] = (eRule[4]-e)/(eRule[4]-eRule[3]); pe = 3; } else if(eRule[4]<=e && e<eRule[5]) { eFuzzy[0] = (eRule[5]-e)/(eRule[5]-eRule[4]); pe = 4; } else if(eRule[5]<=e && e<eRule[6]) { 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<ecRule[0]) { ecFuzzy[0] =1.0; pec = 0; } else if(ecRule[0]<=ec && ec<ecRule[1]) { ecFuzzy[0] = (ecRule[1] - ec)/(ecRule[1]-ecRule[0]); pec = 0 ; } else if(ecRule[1]<=ec && ec<ecRule[2]) { ecFuzzy[0] = (ecRule[2] - ec)/(ecRule[2]-ecRule[1]); pec = 1; } else if(ecRule[2]<=ec && ec<ecRule[3]) { ecFuzzy[0] = (ecRule[3] - ec)/(ecRule[3]-ecRule[2]); pec = 2 ; } else if(ecRule[3]<=ec && ec<ecRule[4]) { ecFuzzy[0] = (ecRule[4]-ec)/(ecRule[4]-ecRule[3]); pec=3; } else if(ecRule[4]<=ec && ec<ecRule[5]) { ecFuzzy[0] = (ecRule[5]-ec)/(ecRule[5]-ecRule[4]); pec=4; } else if(ecRule[5]<=ec && ec<ecRule[6]) { 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); } /*********************************************** 函数功能:PID参数Kd的计算 ************************************************/ float fuzzy_kd(float e, float ec) { float Kd_calcu; uchar num,pe,pec; float code eRule[7]={-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0}; float code ecRule[7]={-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0}; float eFuzzy[2]={0.0,0.0}; float ecFuzzy[2]={0.0,0.0}; float code kdRule[4]={0.0,1.0,2.0,3.0}; float KdFuzzy[4]={0.0,0.0,0.0,0.0}; int code KdRule[7][7]= { 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, 1,1,0,0,0,1,1, 2,2,1,0 ,1,1,1, 3,3,3,3,2,3,2 }; /*****误差隶属函数描述*****/ if(e<eRule[0]) { eFuzzy[0] =1.0; pe = 0; } else if(eRule[0]<=e && e<eRule[1]) { eFuzzy[0] = (eRule[1]-e)/(eRule[1]-eRule[0]); pe = 0; } else if(eRule[1]<=e && e<eRule[2]) { eFuzzy[0] = (eRule[2] -e)/(eRule[2]-eRule[1]); pe = 1; } else if(eRule[2]<=e && e<eRule[3]) { eFuzzy[0] = (eRule[3] -e)/(eRule[3]-eRule[2]); pe = 2; } else if(eRule[3]<=e && e<eRule[4]) { eFuzzy[0] = (eRule[4]-e)/(eRule[4]-eRule[3]); pe = 3; } else if(eRule[4]<=e && e<eRule[5]) { eFuzzy[0] = (eRule[5]-e)/(eRule[5]-eRule[4]); pe = 4; } else if(eRule[5]<=e && e<eRule[6]) { 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<ecRule[0]) { ecFuzzy[0] =1.0; pec = 0; } else if(ecRule[0]<=ec && ec<ecRule[1]) { ecFuzzy[0] = (ecRule[1] - ec)/(ecRule[1]-ecRule[0]); pec = 0 ; } else if(ecRule[1]<=ec && ec<ecRule[2]) { ecFuzzy[0] = (ecRule[2] - ec)/(ecRule[2]-ecRule[1]); pec = 1; } else if(ecRule[2]<=ec && ec<ecRule[3]) { ecFuzzy[0] = (ecRule[3] - ec)/(ecRule[3]-ecRule[2]); pec = 2 ; } else if(ecRule[3]<=ec && ec<ecRule[4]) { ecFuzzy[0] = (ecRule[4]-ec)/(ecRule[4]-ecRule[3]); pec=3; } else if(ecRule[4]<=ec && ec<ecRule[5]) { ecFuzzy[0] = (ecRule[5]-ec)/(ecRule[5]-ecRule[4]); pec=4; } else if(ecRule[5]<=ec && ec<ecRule[6]) { 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 =KdRule[pe][pec]; KdFuzzy[num] += eFuzzy[0]*ecFuzzy[0]; num =KdRule[pe][pec+1]; KdFuzzy[num] += eFuzzy[0]*ecFuzzy[1]; num =KdRule[pe+1][pec]; KdFuzzy[num] += eFuzzy[1]*ecFuzzy[0]; num =KdRule[pe+1][pec+1]; KdFuzzy[num] += eFuzzy[1]*ecFuzzy[1]; /********加权平均法解模糊********/ Kd_calcu=KdFuzzy[0]*kdRule[0]+KdFuzzy[1]*kdRule[1]+KdFuzzy[2]*kdRule[2] +KdFuzzy[3]*kdRule[3]; 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) { for(i=0;i<8;i++) { CLK = 0; if(Temp&0x80) SDI = 1; else SDI = 0; AD_value<<=1; if(SDO) AD_value |= 0x01; CLK = 1; Temp<<=1; } for(i=8;i<12;i++) { CLK = 0; AD_value<<=1; if(SDO) AD_value |= 0x01; delay_us(10); CLK = 1; } CLK = 0; CS = 1; if(PORT == port) break; else { Temp = port; Temp<<=4; delay_us(10); CS = 0; AD_value = 0; } k++; if(k>2) { PORT = port; } } return AD_value; } float AD_deal(void) { uint AD_value; float temp; AD_value = read_tlc2543(0x00); temp = AD_value*number; return temp; } /*********主函数**********/ void main(void) { uchar AD_value=0; flag=0;    flag_start=0; ENA=1; IN1=0; 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);
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服