基于51單片機的水溫控制系統制作
適合于51單片機愛好者
壓縮文件里有制作過程、代碼與原理圖。
本系統設計采用基于PID算法的單片機控制來實現水溫的調控。單片機控制部分采用AT89C51單片機為核心,采用軟件編程,實現用PID算法來控制PWM波的產生,繼而控制電爐的加熱來實現溫度控制。通過編程對PID各參數的調整,來達到提高加溫速度,減小超調的目的。 設計任務和主要內容 一升水在1kw電爐下加熱,要求水溫在一定范圍內可由人工設定,并能在環境溫度降低時自動調節,以保證設定的溫度基本不變。 - 溫度設定范圍為40~90℃,最小區分度為1℃,標定溫度小于等于1℃。
- 環境溫度降低時溫度控制的靜態誤差小于等于1℃。
- 用十進制數碼管顯示水的溫度。
- 采用適當的控制方法,當設定的溫度突變時,減小系統的調節時間和超調量。
- 溫度控制的靜態誤差小于等于0.2℃。
- 在設定溫度發生突變時,自動打印水溫隨時間變化的曲線。
- 系統設計原理
該水溫控制系統主要由AT89S52單片機控制系統、溫度采樣轉換器、溫度控制電路。鍵盤顯示電路等四部分組成,總體框圖如上。 (一)總體方案論證 根據題目的要求,我們提出了以下三種方案: 方案1:采用傳統的二位模擬控制方法,選用模擬電路,用電位器設定給定值,采用上下限比較電路將反饋的溫度值與給定的值比較后,決定加熱或者不加熱。由于采用的模擬控制方式,系統受環境影響較大,不能實現復雜的控制算法使控制精度做得較高,而且不能用于顯示和鍵盤設定。 方案2:采用單片機AT89S52為核心。采用數字溫度傳感器DS18B20采集溫度變化信號,將其轉換成數字信號并通過單片機處理后去控制溫度,使其達到穩定。使用單片機具有編程靈活,控制簡單的優點,使系統能簡單的實現溫度的控制及顯示,并且通過軟件編程能實現各種控制算法使系統還具有控制精度高的特點。 比較上述兩種方案,方案2明顯改善了方案1的不足,具有控制簡單、控制溫度精度高的特點,因此本設計電路采用方案2。 (二)各部分電路方案論證 1、溫度采樣部分 方案1:采用熱敏電阻,可滿足35℃--95℃的測量范圍,但熱敏電阻精度、重復性和可靠性都比較差,對于檢測精度小于1℃的溫度信號是不適用的。 方案2:采用數字溫度傳感器DS18B20。DS18B20是支持一線總線接口的溫度傳感器,具有抗干擾性強,體積小,靈活經濟的特點。它的測量溫度范圍為-55℃~+125℃,在-10℃~+85℃范圍內,精度為±0.5℃且有9~12位分辨率可調,使用電壓為3~5V無需備用電源。此外DS18B20集合了64位光刻ROM、溫度傳感器、非揮發的溫度報警觸發器TH和TL、配置寄存器,可以直接實現溫度的測量和轉換,無需再另接外部電路。 方案3:采用溫度傳感器AD590。AD590具有體積小、質量輕、線性度好、性能穩定等優點。其測量范圍在-50℃~+150℃,滿刻度范圍誤差為 ±0.3℃,當電源電壓在5~10之間,穩定度為1%時誤差只有±0.01℃,此外,AD590是溫度—電流傳感器,對于提高系統抗干擾能力有很大幫助。 從系統電路設計的復雜度,性價比等方面考慮,決定選用方案2。 2、控制電路部分 方案1:可以用邏輯電路搭建一個控制器,實現PID控制。但系統還要附加顯示、溫度設定等功能,要附加很多電路,總體的電路設計和制作比較繁瑣。 方案2:采用8031芯片,其內部沒有程序存儲器,需要進行外部拓展,這給電路增加了復雜度。 方案3:本方案的CPU模塊采用2051芯片,其內部有2KB單元的程序存儲器,不需要外部拓展程序存儲器,但由于系統用到較多的I/O口,因此此芯片的資源不夠用。 方案4:采用AT89S52單片機,其內部有8KB單元的程序存儲器,不需要外部擴展程序存儲器,而且其I/O口達32個,完全滿足本次設計需要。 比較這4種方案,綜合的考慮單片機各部分資源,本次設計選用方案4。 3、加熱方案和功率電路的選擇 方案1:加熱的裝置,根據題目,可以使用電熱爐進行加熱,控制電爐的功率豈可控制加熱速度。水溫過高時,一般只能關掉電爐,讓其自然冷卻。為求更好的控制效果,也可以裝置一個小風扇,電爐加熱時風扇關閉,水溫超高時關閉電爐開啟風扇加速散熱。 方案2:可以采用可控硅控制加熱器的工作。通過單片機產生PWM信號來控制可控硅的導通和關斷,控制加熱器的加熱時間,從而控制加熱器的功率。   從加熱的響應速度考慮,采用方案2。因為加熱的功率較大,故電源采用市電220伏。 設計電路圖如圖2所示
 DS18B20  ISP下載口
AT89S52主控電路 MOC3041功率電路 LCD液晶顯示
 PCB圖如下:
功率電路 主控電路
本設計總體包括四個部分:主機控制部分、溫度采樣轉換部分、溫度控制部分、鍵盤顯示部分。 溫度采樣轉換電路
系統的溫度采樣轉換由DS18B20集成芯片來實現。電路圖如右 DS18B20性能描述 測量范圍在-55℃~+125℃,在-10℃~+85℃范圍內,精度為±0.5℃且有9~12位分辨率可調,使用電壓為3~5V,無需備用電源。 DS18B20采用單總線通信技術,通信穩定可靠,且線路簡單,容易實現。 其基本的通信過程如下: 主機拉低單總線產生至少480us的Tx復位脈沖; 然后由主機釋放總線,進入Rx接收模式,主機釋放總線時會產生一個由低電平變為高電平的上升沿; 單總線器件檢測到該上升沿后,延時15~60us; 單總線器件通過拉低總線60~240us來產生應答脈沖; 主機接收到從機的應答信號后,說明有單總線器件在線,然后主機就可以開始對從機進行ROM命令和功能命令操作。 DS18B20直接輸出數字量,可直接與單片機進行通信,讀取測溫數據,電路非常簡單。使用它,主要工作量集中在了單片機編程上。  此部分電路主要由光電耦合器MOC3041和雙向可控硅BTA16組成。以脈寬調制輸出控制電爐與電源的接通和斷開比例,以通斷控制調壓法控制電爐的輸入功率。MOC3041的內部集成了發光二極管、過零檢測電路和一個小功率雙向可控硅。當單片機PWM輸出為1,MOC3041中的發光二極管發光,用于過零檢測電路的同步作用,內部的雙向可控硅在過零后馬上導通,從而使觸發雙向可控硅BTA16導通,負載中有電流通過,反之當單片機PWM輸出為0,雙向可控硅截止,負載中沒有電流通過。光電耦合的耐壓值為400v,它的輸出級由過零觸發的雙向可控硅構成,它控制著主電路雙向可控硅的導通和關閉。控制部分電路圖如下
3、單片機控制部分 此部分是該系統的核心,系統的控制采用了單片機AT89S52。單片機AT89S52內部有8KB字節的可編程FLASH存儲器和256字節的數據存儲器。故系統不必外拓存儲器,這樣大大減少了系統的硬件電路。電路原理圖如下:
4、按鍵及顯示部分 系統僅采用五個按鍵來進行溫度的控制。 在顯示方面,我們采用了LCD1602的液晶顯示模塊,通過軟件編程,可以實現所需要的顯示。此外,液晶模塊的使用也比較簡單,只要連接數據總線,選通端口和命令/數據端口即可。 系統的硬件設計盡量簡單,故工作任務主要在程序的設計上。
PID算法控制PWM輸出:
程圖如下
- void timer0() interrupt 1
- {
- uchar flag;
- TH0=0xd8 ; 有
- TL0=0xf0 ;
- TR1=1 ; 無
- P24=1 ; //啟動輸出
- CJ++;
- if(stemp>Wtemperature) flag=0
- {
- ei=stemp-Wtemperature; flag=1
- E=E+ei;
- ex=ej-ei;
- ej=ei;
- if(ei<6)
- {Ui=U0-Kp*(ei+Ti*E-Td*ex);}
- else Ui=U0-Kp*ei;
- flag=Ui/100;
- switch(flag)
- {
- case 9:{TH1=0xdc;TL1=0xd8;}break;
- case 8:{TH1=0xe2;TL1=0xb4;}break;
- case 7:{TH1=0xe8;TL1=0x90;}break;
- case 6:{TH1=0xec;TL1=0x78;}break;
- case 5:{TH1=0xf0;TL1=0x60;}break;
- case 4:{TH1=0xf2;TL1=0x54;}break;
- case 3:{TH1=0xf4;TL1=0x48;}break;
- case 2:{TH1=0xf8;TL1=0x30;}break;
- case 1:{TH1=0xfc;TL1=0x18;}break;
- case 0:{TH1=0xfd;TL1=0xa8;}break;
- default:{TH1=0xff;TL1=0xfa;}break;
- }
- }
- else {TH1=0xff;TL1=0xfa;}
- }
復制代碼程序用T0和T1的嵌套來實現PWM波,T0控制波的頻率,T1控制占空比,其效果圖如下:
PID控制器: PID控制器采用單片機軟件實現。輸出PWM控制信號,定時器采用T0,T1的嵌套,T0定時是10MS,T1控制低電平的輸出。由于加熱器屬于帶滯后的一階對象,故式中Kp,Ki,Kd的選擇取決于加熱器的階躍響應特性和實際經驗,為了實現PID參數的實時整定,各溫度區間由實驗測取最佳的Kp,Ki,Kd值。
1、動態溫控測量 測量方式:接上系統的加熱裝置,裝入1L室溫的水,設定溫控溫度。記錄調節時間、超調溫度、穩態溫度波動幅度等。 測量條件:環境溫度18℃,加熱器功率1000W。 測量結果數據 2、結果分析 由以上測量結果可見,系統性能基本達到了所要求的指標。 在溫控指標中,影響系統性能的因素很多,最關鍵的是加熱器本身的物理 性質及控制算法。傳感器必須加上防水設施,故溫度傳感難免遲滯,加熱器的加熱本身有延遲,水對流傳熱也會造成測溫的延遲,這些都會直接影響系統的控制性能。控制算法方面,需反復實驗比較,在上升時間和超調量之間做權衡,選出綜合效果最好的PID系數。 因為是直接接入220V的市電,當電路一通電,板面溫度突然升高,以致燒壞電路板。于是之后我們在電路中加上了散熱片。 溫度傳感器DS18B20不能直接浸在水中測溫度,故我們將其固定在一導熱性相對好的金屬筒內,再沒入水中測量。 功率電路的輸出端原本應該加上一個電容來矯正零相位,然而當硬件電路都裝好后,進行調試,發現加熱器一直工作,沒有辦法實現溫度的控制,檢查發現是電容的問題。當加上電容時,在交流電的作用下,電路直接導通,根本不需要外加控制,故我們去掉了該電容,加熱器這才受控。 本系統設計是以AT89S51單片機為核心,采用軟件編程,運用PID算法來控制PWM波的產生,繼而控制加熱器的加熱時間來實現溫度的控制。在軟硬件的調試過程中,出現了不少問題,如電路板發燙,程序不起作用,加熱速度較慢等,但是在老師和同學的指導和幫助下,通過電路檢查,程序修改等工作,問題基本上都得到了解決。在這一次設計過程中,我們了解了很多專業知識,動手能力也得到了提高。然而,系統還存在著一些問題,如水溫達到穩定的時間。
單片機源程序如下:
- /***************************************************************
- 項目名稱:水溫控制系統設計;
- 功 能:通過STC89C52單片機控制可控硅驅動加過零檢測電路作為
- 功率控制電路來控制加熱過程,通過鍵盤掃描來設定水溫,
- DS18B20實時測量水的溫度,將實際水溫與設定水溫比較
- 通過PID控制算法調節,是實際水溫與設定水溫接近。從而
- 達到控制水溫的目的。
- 作 者:0903 藺一鋒
- 日 期:2010年11月3日
- ***************************************************************/
- #include<reg52.h>
- #include<stdio.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit s1=P2^0;
- sbit s2=P2^1;
- sbit s3=P2^2;
- sbit s4=P2^3;
- sbit s5=P2^4;
- sbit ds=P2^5;
- sbit beep=P2^6;
- sbit rd=P1^0;
- sbit rs=P1^1;
- sbit wr=P1^2;
- sbit lcden=P1^3;
- sbit PWM=P1^6;
- sbit led1=P1^4;
- sbit led2=P1^5;
- uchar set_temp,keytemp;
- uint temp;
- uchar c;
- bit flag,flag1,flag2;
- float f_temp,t;
- int timecount,z;
- float KP,KI,KD;
- float e1,e2,e3;
- float uk,duk;
- uchar HighL,HighH,PWMH;
- float k;
- uchar code table[]={"設定溫度:"};
- uchar code table1[]={"實測溫度:"};
- uchar code table2[]={"加熱"};
- uchar code table3[]={"保溫"};
- uchar code table4[]={"作者:0903鋒仔@"};
- uchar code table5[]={"系統初始化"};
- uchar code table6[]={"measured Temperature"};
- uchar code table7[]={"水溫控制系統設計"};
- uchar code table8[]={" "};
- void delay(uint z)//延時函數,延時5ms
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /***************************************
- 鍵盤掃描函數
- 通過S5,S4,S3,S2,S1鍵來分別實現溫度設定值的
- 粗加,粗減,精加,精減,和確定功能。
- ***************************************/
- void keyscan()
- {
- if(set_temp>=100)//將設定溫度限定在0-100度之間
- set_temp=100;
- if(set_temp<=0)
- set_temp=0;
- if(s5==0)//此鍵按下設定溫度加5
- {
- delay(10);
- if(s5==0)
- {
- flag1=0;
- set_temp+=5;
- if(set_temp>=100)
- {
- set_temp=100;
- beep=0;
- delay(1000);
- beep=1;
- }
- }while(s5==0);
- }
- if(s4==0)//此鍵按下設定溫度減5
- {
- delay(10);
- if(s4==0)
- {
- flag1=0;
- set_temp-=5;
- if(set_temp<=0)
- {
- set_temp=0;
- beep=0;
- delay(1000);
- beep=1;
- }
- }while(s4==0);
- }
- if(s3==0)//此鍵按下設定溫度加1
- {
- delay(10);
- if(s3==0)
- {
- flag1=0;
- set_temp++;
- if(set_temp==100)
- {
- set_temp=100;
- beep=0;
- delay(1000);
- beep=1;
- }
- }while(s3==0);
- }
- if(s2==0)//此鍵按下設定溫度減1
- {
- delay(10);
- if(s2==0)
- {
- flag1=0;
- set_temp--;
- if(set_temp==0)
- {
- set_temp=0;
- beep=0;
- delay(1000);
- beep=1;
- }
- }while(s2==0);
- }
- if(s1==0)//確定加熱狀態(加熱與不加熱)
- {
- delay(10);
- if(s1==0)
- {
- flag1=1;
- }
- while(s1==0);
- }
- }
- /******************************************
- DS18B20溫度采集模塊程序設計
- 通過DS18B20實時采集水溫,反映給單片機系統
- ******************************************/
- void dsreset()//DS18B20復位函數
- {
- uint i;
- ds=0;
- i=103;
- while(i>0)i--;
- ds=1;
- i=4;
- while(i>0)i--;
- }
- bit tempreadbit()//從DS18B20 RAM讀一位數據
- {
- uint i;
- bit dat;
- ds=0;i++;
- ds=1;i++;i++;
- dat=ds;
- i=8;while(i>0)i--;
- return(dat);
- }
- uchar tempread()//從DS18B20 RAM讀一字節數據
- {
- uchar i,j,dat;
- dat=0;
- for(i=1;i<=8;i++)
- {
- j=tempreadbit();
- dat=(j<<7)|(dat>>1);
- }
- return(dat);
- }
- void tempwritebyte(uchar dat)//向DS18B20寫以字節的數據
- {
- uint i,j;
- bit testb;
- for(j=1;j<=8;j++)
- {
- testb=dat&0x01;
- dat=dat>>1;
- if(testb)//寫1
- {
- ds=0;
- i++;i++;
- ds=1;
- i=8;while(i>0)i--;
- }
- else//寫0
- {
- ds=0;
- i=8;while(i>0)i--;
- ds=1;
- i++;i++;
- }
- }
- }
- /*void readrom()
- {
- dsreset();
- delay(1);
- tempwritebyte(0x33);
- tempwritebyte(0xbe);
- readrom=tempread();
- }
- void matchrom()
- {
- dsreset();
- delay(1);
- tempwritebyte(0x55);
- }*/
- void tempchange()//啟動溫度轉換
- {
- dsreset();
- delay(1);
- tempwritebyte(0xcc);
- tempwritebyte(0x44);
- }
- float get_temp()//溫度值讀取與處理函數
- {
- uchar a,b;
- dsreset();
- delay(1);
- tempwritebyte(0xcc);
- tempwritebyte(0xbe);
- a=tempread();
- b=tempread();
- temp=b;
- temp<<=8;
- temp=temp|a;
- f_temp=(float)(temp*0.0625);
- f_temp=f_temp*10;
- return(f_temp);
- }
- /**********************************************
- 12864顯示模塊
- 顯示實際溫度制和設定溫度值
- **********************************************/
- void write_com(uchar com)//向12864寫指令
- {
- rs=0;
- wr=0;
- delay(1);
- P0=com;
- lcden=1;
- delay(1);
- lcden=0;
- delay(1);
- }
- void write_date(uchar date)//向12864寫數據
- {
- rs=1;
- wr=0;
- delay(1);
- P0=date;
- lcden=1;
- delay(1);
- lcden=0;
- delay(1);
- }
- void display(float m,uchar n)//顯示設定溫度、實測溫度、加熱狀態
- {
- uint i,j;
- float b;
- float p;
- uchar a1,a2,a3;
- uchar b1,b2,b3,b4;
- if(n<100)
- {
- a1=0;
- a2=n/10;
- a3=n%10;
- }
- else
- {
- a1=1;
- a2=0;
- a3=0;
- }
- p=m;
- j=(uint)(p*10);
- b1=(uchar)(j/1000);
- b2=(uchar)(j%1000/100);
- b3=(uchar)(j%100/10);
- b4=(uchar)(j%10);
- write_com(0x90+5);//顯示設定溫度
- write_date(0x30+a1);
- write_date(0x30+a2);
- write_date(0x30+a3);
- write_com(0x88+5);//顯示實測溫度
- write_date(0x30+b1);
- write_date(0x30+b2);
- write_date(0x2e);
- write_date(0x30+b3);
- write_date(0x30+b4);
- b=((float)(b1*100+b2*10+b3))/10.0;
- i=0;
- if((b+0.2)<n)
- {
- led1=0;
- write_com(0x98+1);
- while(table2[i]!='\0')
- {
- write_date(table2[i]);
- i++;
- }
- flag2=1;
- }
- else
- {
- led1=1;
- i=0;
- write_com(0x98+1);
- while(table8[i]!='\0')
- {
- write_date(table8[i]);
- i++;
- }
- i=0;
- if((b=n)||((b>n)&&((b-0.2)<=n))||((b<n)&&((b+0.2)>=n)))
- {
- led2=0;
- write_com(0x98+4);
- while(table3[i]!='\0')
- {
- write_date(table3[i]);
- i++;
- }
- }
- }
- if(flag2==1)
- {
- flag2=0;
- led2=1;
- i=0;
- write_com(0x98+4);
- while(table8[i]!='\0')
- {
- write_date(table8[i]);
- i++;
- }
- }
- }
- /*****************************************************
- PID控制算法程序設計
- 通過PID控制算法可以使實際水溫在設定水溫周圍呈很小范圍的
- 波動,從而使實際水溫值接近設定水溫值
- *****************************************************/
- void conversion()//定時器2初值處理函數
- {
- uint temp2;
- temp2=65536-PWMH*10;
- HighH=temp2/256;
- HighL=temp2%256;
- }
- void senddate(float y)
- {
- // uint i;
- if(flag==1)
- {
- ES=0;
- flag=0;
- c=0;
- TI=1;
- printf("The measured temp:%f",y);
- // SBUF=1;
- while(!TI);
- TI=0;
- ES=1;
- }
- }
- void init()//初始化函數
- {
- uint i,j;
- TMOD=0x21;
- TH1=0xfd;
- TL1=0xfd;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- PWMH=0;
- conversion();
- TH2=(65536-50000)/256;
- TL2=(65536-50000)%256;
- rd=1;
- lcden=0;
- write_com(0x30);
- write_com(0x0c);
- write_com(0x01);
- write_com(0x90);
- while(table5[i]!='\0')//系統初始化
- {
- write_date(table5[i]);
- i++;
- delay(20);
- }
- for(j=0;j<=1;j++)//6個點的三次循環
- {
- write_com(0x88+4);
- for(i=0;i<=5;i++)
- {
- write_date(0x2e);
- delay(200);
- }
- delay(100);
- write_com(0x88+4);
- for(i=0;i<=5;i++)
- {
- write_date(0x20);
- }
- delay(100);
- }
- i=0;
- write_com(0x80);//顯示 水溫控制系統設計標題
- while(table7[i]!='\0')
- {
- write_date(table7[i]);
- i++;
- }
- i=0;
- write_com(0x90);//顯示 設定溫度
- while(table[i]!='\0')
- {
- write_date(table[i]);
- i++;
- }
- i=0;
- write_com(0x88);//顯示 實測溫度
- while(table1[i]!='\0')
- {
- write_date(table1[i]);
- i++;
- }
- // tempwritebyte(0x4e);//設定DS18B20的分辨率為11位
- // tempwritebyte(0x5f);
- PWM=0;
- e1=0;
- e2=0;
- e3=0;
- duk=0;
- uk=0;
- KP=20;//PID控制算法參數
- KI=0.061;
- KD=30;
- REN=1;//串口通信設置
- SM0=0;
- SM1=1;
- ET0=1;
- ET2=1;
- TR0=1;
- TR1=1;
- TR2=1;//啟動定時器2
- EA=1;
- ES=1;
- }
- void main()
- {
- init();
- while(1)
- {
- keyscan();//調用鍵盤掃描函數
- tempchange();//啟動溫度轉換
- t=get_temp();//提取實測溫度
- display(t,set_temp);//顯示設定溫度和實測溫度
- senddate(t);//向上位機發送數據函數
- if((flag1==1))
- {
- if(timecount>=375)
- {
- timecount=0;
- e1=set_temp-t;
- duk=(KP*(e1-e2)+KI*e1+KD*(e1-2*e2+e3));//PID控制算法式
- uk=uk+duk;
- if(e1>=75)
- {
- z=4;
- }
- else if(e1>=50)
- {
- z=3;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
基于51單片機的水溫控制系統.rar
(18.56 MB, 下載次數: 916)
2018-7-20 16:53 上傳
點擊文件名下載附件
|