|
單片機(jī)源程序如下:
- /********************************************************************
- 模糊PID控制溫控系統(tǒng)仿真設(shè)計(jì)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;
- /******************************
- 函數(shù)功能:延時(shí)
- ******************************/
- 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);
- }
- /***********************************
- 函數(shù)功能:顯示函數(shù)
- *************************************/
- 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);
- }
- /************************************
- 函數(shù)功能:定時(shí)器2初始化
- *************************************/
- void Timer2_Init()
- {
- RCAP2H =(65536-300)/256;
- RCAP2L =(65536-300)%256;
- TH2 = RCAP2H;
- TL2 = RCAP2L;
- ET2 = 1;
- TR2 = 1;
- EA = 1;
- }
- /*************************************
- 函數(shù)功能:鍵盤(pán)掃描,調(diào)整設(shè)置溫度
- ****************************************/
- 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);
- }
- }
- }
- /************************************
- 函數(shù)功能:PID的計(jì)算
- **********************************/
- 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;
- }
- }
- /***********************************************
- 函數(shù)功能:PID參數(shù)Kp的計(jì)算
- ************************************************/
- 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隸屬函數(shù)描述*****/
- 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隸屬函數(shù)描述*****/
- 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];
- /*********查詢模糊規(guī)則表*********/
- 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];
- /*********加權(quán)平均法解模糊*********/ Kp_calcu=KpFuzzy[0]*kpRule[0]+KpFuzzy[1]*kpRule[1]+KpFuzzy[2]*kpRule[2]
- +KpFuzzy[3]*kpRule[3];
- return(Kp_calcu);
- }
- /***********************************************
- 函數(shù)功能:PID參數(shù)Ki的計(jì)算
- ************************************************/
- 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
- };
- /*****誤差隸屬函數(shù)描述*****/
- 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];
- /*****誤差變化隸屬函數(shù)描述*****/
- 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];
- /***********查詢模糊規(guī)則表***************/
- 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];
- /********加權(quán)平均法解模糊********/ Ki_calcu=KiFuzzy[0]*kiRule[0]+KiFuzzy[1]*kiRule[1]+KiFuzzy[2]*kiRule[2]
- +KiFuzzy[3]*kiRule[3];
- return(Ki_calcu);
- }
- /***********************************************
- 函數(shù)功能:PID參數(shù)Kd的計(jì)算
- ************************************************/
- 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
- };
- /*****誤差隸屬函數(shù)描述*****/
- 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];
-
- /*****誤差變化隸屬函數(shù)描述*****/
- 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];
- /***********查詢模糊規(guī)則表*************/
- 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];
- /********加權(quán)平均法解模糊********/
- Kd_calcu=KdFuzzy[0]*kdRule[0]+KdFuzzy[1]*kdRule[1]+KdFuzzy[2]*kdRule[2]
- +KdFuzzy[3]*kdRule[3];
- return(Kd_calcu);
- }
- /*****************************************
- 函數(shù)功能:AD將采集到的溫度進(jìn)行轉(zhuǎn)化
- ********************************************/
- 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;
- }
- /*********主函數(shù)**********/
- 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);
- 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);
- }
- }
- }
- /***************定時(shí)器2中斷**************/
- void timer2() interrupt 5
- {
- static uchar num1=0;
- TF2 = 0;
- num1++;
- if(num1<=U)
- {
- if(flag==1)
- {
- IN1 = 0;
- IN2 = 1;
- }
- else
- {
- IN1 = 1;
- IN2 = 0;
- }
- }
- else
- ENA=0;
- if(num1>PULSE)
- {num1=0;ENA=1;}
- }
復(fù)制代碼
所有資料51hei提供下載:
模糊PID控制溫控系統(tǒng)設(shè)計(jì)C語(yǔ)言程序代碼.doc
(120.5 KB, 下載次數(shù): 212)
2018-3-10 14:35 上傳
點(diǎn)擊文件名下載附件
|
|