基于51单片机的智能加湿器控制proteus仿真系统设计
本設計
51單片機智能加濕器控制系統proteus仿真(仿真+源碼+原理圖)
仿真圖proteus 7.8
程序編譯器:keil 4/keil 5
編程語言:C語言
設計編號C0043
資料下載鏈接(可點擊)
主要功能:
本設計由STC89C52單片機+溫濕度傳感器電路+按鍵電路+液位傳感器電路+液晶1602顯示電路+LED指示燈電路+蜂鳴器報警電路+電源電路組成。
1、液晶實時顯示濕度值(濕度范圍10%-95%)和濕度閾值。
2、有2個按鍵,可通過按鍵設置濕度閾值范圍。
3、當濕度值小于閾值,綠燈亮,否則綠燈不亮。
4、通過液位傳感器檢測液位,液位有3種狀態:低(L)、高(H)、正常(N),并在液晶實時顯示。并用3個指示燈模擬顯示。低液位時黃燈亮,正常液位藍燈亮,高液位是紅燈亮(仿真時液位用按鍵模擬)。
5、當液位低于低液位時,停止加濕即綠燈滅,同時蜂鳴器報警。否則蜂鳴器不報警。
仿真圖(提供源文件)
仿真圖講解:
單片機最小系統介紹
單片機(Microcontrollers)是一種集成電路芯片,是采用超大規模集成電路技術把具有數據處理能力的中央處理器CPU、隨機存儲器RAM、只讀存儲器ROM、多種I/O口和中斷系統、定時器/計數器等功能(可能還包括顯示驅動電路、脈寬調制電路、模擬多路轉換器、A/D轉換器等電路)集成到一塊硅片上構成的一個小而完善的微型計算機系統,在工業控制領域廣泛應用。從上世紀80年代,由當時的4位、8位單片機,發展到現在的300M的高速單片機。本文的單片機特指51單片機,具體芯片型號是STC89C52RC。需注意STC89C51,STC89C52,AT89C51,AT89C52都是51單片機的一種具體芯片型號。
最小系統組成:
51單片機最小系統:單片機、復位電路、晶振(時鐘)電路、電源
最小系統用到的引腳
1、主電源引腳(2根)
VCC:電源輸入,接+5V電源
GND:接地線
2、外接晶振引腳(2根)
XTAL1:片內振蕩電路的輸入端
XTAL2:片內振蕩電路的輸出端
3、控制引腳(4根)
RST/VPP:復位引腳,引腳上
復位電路
在電路圖中,電容的的大小是10uf,電阻的大小是0.56k。
在5V正常工作的51單片機中小于1.5V的電壓信號為低電平信號,而大于1.5V的電壓信號為高電平信號。可以算出電容充電到電源電壓的0.7倍,即電容兩端電壓為3.5V、電阻兩端電壓為1.5V時,需要的時間約為T=RC=0.56K*10UF=0.056S。
也就是說在單片機上電啟動的0.1S內,電容兩端的電壓從0-3.5V不斷增加,這個時候10K電阻兩端的電壓為從5-1.5V不斷減少(串聯電路各處電壓之和為總電壓),所以RST引腳所接收到的電壓是5V-1.5V的過程,也就是高電平到低電平的過程。
單片機RST引腳是高電平有效,即復位;低電平無效,即單片機正常工作。所以在開機0.056內,單片機系統RST引腳接收到了時間為0.056S左右的高電平信號,所以實現了自動復位。
在單片機啟動0.056S后,電容C兩端的電壓持續充電為5V,這是時候10K電阻兩端的電壓接近于0V,RST處于低電平所以系統正常工作。當按鍵按下的時候,開關導通,這個時候電容兩端形成了一個回路,電容被短路,所以在按鍵按下的這個過程中,電容開始釋放之前充的電量。隨著時間的推移,電容的電壓在0.056S內,從5V釋放到變為了1.5V,甚至更小。根據串聯電路電壓為各處之和,這個時候10K電阻兩端的電壓為3.5V,甚至更大,所以RST引腳又接收到高電平。單片機系統自動復位。
晶振電路
晶振基本概念 晶振全名叫晶體振蕩器,每個單片機系統里都有晶振,晶振是由石英晶體經過加工并鍍上電極而做成的,主要的特性就是通電后會產生機械震蕩,可以給單片機提供穩定的時鐘源,晶振提供時鐘頻率越高,單片機的運行速度也就越快。 晶振用一種能把電能和機械能相互轉化的晶體在共振的狀態下工作,以提供穩定,精確的單頻振蕩。
晶振起振后, 產生的振動信號會通過XTAL1引腳, 依次經過振蕩器和時鐘發生器的處理,得到機器周期信號,作為指令操作的依據。51單片機常用的晶振是12M和11.0592M。本設計使用12M晶振
LCD1602顯示
第1引腳:GND為電源地
第2引腳:VCC接5V電源正極
第3引腳:V0為液晶顯示器對比度調整端,接正電源時對比度最弱,接地電源時對比度最高(對比度過高時會 產生“鬼影”,使用時可以通過一個10K的電位器調整對比度)。
第4引腳:RS為寄存器選擇,高電平1時選擇數據寄存器、低電平0時選擇指令寄存器。
第5引腳:RW為讀寫信號線,高電平(1)時進行讀操作,以51為例的簡單原理圖低電平(0)時進行寫操作。
第6引腳:E(或EN)端為使能(enable)端,高電平(1)時讀取信息,負跳變時執行指令。
第7~14引腳:D0~D7為8位雙向數據端。第15~16腳:空腳或背燈電源。第15引腳背光正極,第16引腳背光負極。
SHT11溫濕度傳感器
仿真圖中各引腳的功能如下:
其中DA-TA為數據線,SCK為時鐘線;
蜂鳴器電路
通過三極管控制,P12給高電平導通,蜂鳴器響。
指示燈電路
灌電流設計,單片機給低電平點亮LED燈。
原理圖(提供源文件,僅供參考)
程序(提供源文件源碼)
LCD1602顯示驅動函數
/*********************************************************/ // 毫秒級的延時函數,time是要延時的毫秒數 /*********************************************************/ void DelayMs(uint time) {uint i,j;for(i=0;i<time;i++)for(j=0;j<112;j++); } /*********************************************************/ // 1602液晶寫命令函數,cmd就是要寫入的命令 /*********************************************************/ void LcdWriteCmd(uchar cmd) { LcdRs_P = 0;LcdRw_P = 0;LcdEn_P = 0;P0=cmd;DelayMs(2);LcdEn_P = 1; DelayMs(2);LcdEn_P = 0; }/*********************************************************/ // 1602液晶寫數據函數,dat就是要寫入的數據 /*********************************************************/ void LcdWriteData(uchar dat) {LcdRs_P = 1; LcdRw_P = 0;LcdEn_P = 0;P0=dat;DelayMs(2);LcdEn_P = 1; DelayMs(2);LcdEn_P = 0; }/*********************************************************/ // 1602液晶初始化函數 /*********************************************************/ void LcdInit() {LcdWriteCmd(0x38); // 16*2顯示,5*7點陣,8位數據口LcdWriteCmd(0x0C); // 開顯示,不顯示光標LcdWriteCmd(0x06); // 地址加1,當寫入數據后光標右移LcdWriteCmd(0x01); // 清屏 }/*********************************************************/ // 液晶光標定位函數 /*********************************************************/ void LcdGotoXY(uchar line,uchar column) {// 第一行if(line==0) LcdWriteCmd(0x80+column); // 第二行if(line==1) LcdWriteCmd(0x80+0x40+column); }/*********************************************************/ // 液晶輸出字符串函數 /*********************************************************/ void LcdPrintStr(uchar *str) {while(*str!='\0') // 判斷是否到字符串的盡頭了LcdWriteData(*str++); }/*********************************************************/ // 液晶輸出數字 /*********************************************************/ void LcdPrintNum(uchar num) {LcdWriteData(num/10+48); // 十位LcdWriteData(num%10+48); // 個位 }SHT11溫濕度傳感器驅動
/*********************************************************/ // 往SHT11寫入一個字節 /*********************************************************/ char ShtWriteByte(uchar value) {uchar i,error=0;for(i=128;i>0;i>>=1) // 高位為1,循環右移{if (i&value) Data_P=1; // 和要發送的數相與,結果為發送的位else Data_P=0;Sck_P=1;_nop_(); // 延時3us_nop_();_nop_(); Sck_P=0;}Data_P=1; // 釋放數據線Sck_P=1;error=Data_P; // 檢查應答信號,確認通訊正常_nop_();_nop_();_nop_();Sck_P=0;Data_P=1;return error; // error=1 通訊錯誤 }/*********************************************************/ // 從SHT11讀出一個字節 /*********************************************************/ char ShtReadByte(uchar ack) {unsigned char i,val=0;Data_P=1; // 釋放數據線for(i=0x80;i>0;i>>=1) // 高位為1,循環右移{Sck_P=1;if(Data_P) val=(val|i); // 讀一位數據線的值Sck_P=0;}Data_P=!ack; // 如果是校驗,讀取完后結束通訊Sck_P=1;_nop_(); // 延時3us_nop_();_nop_();Sck_P=0;_nop_();_nop_();_nop_();Data_P=1; // 釋放數據線return val; }/*********************************************************/ // SHT11啟動傳輸 /*********************************************************/ void ShtTransStart(void) {Data_P=1; Sck_P=0; _nop_();Sck_P=1;_nop_();Data_P=0;_nop_();Sck_P=0;_nop_();_nop_();_nop_();Sck_P=1;_nop_();Data_P=1;_nop_();Sck_P=0; }/*********************************************************/ // SHT11連接復位 /*********************************************************/ void ShtConnectReset(void) {unsigned char i;Data_P=1; //準備Sck_P=0; for(i=0;i<9;i++) //DATA保持高,SCK時鐘觸發9次,發送啟動傳輸,通迅即復位{Sck_P=1;Sck_P=0;}ShtTransStart(); //啟動傳輸 }/*********************************************************/ // SHT11溫濕度檢測 /*********************************************************/ char ShtMeasure(unsigned char *p_value, unsigned char *p_checksum, uchar mode) {unsigned error=0;unsigned int i;ShtTransStart(); // 啟動傳輸switch(mode) // 選擇發送命令{case 1 : // 測量溫度error+=ShtWriteByte(0x03); break; case 2 : // 測量濕度error+=ShtWriteByte(0x05); break; default: break;}for(i=0;i<65535;i++) if(Data_P==0) break; // 等待測量結束if(Data_P) error+=1; // 如果長時間數據線沒有拉低,說明測量錯誤*(p_value) =ShtReadByte(1); // 讀第一個字節,高字節 (MSB)*(p_value+1)=ShtReadByte(1); // 讀第二個字節,低字節 (LSB)*p_checksum =ShtReadByte(0); // read CRC校驗碼return error; // error=1 通訊錯誤 }/*********************************************************/ // SHT11溫濕度值標度變換及溫度補償 /*********************************************************/ void CalcSHT11(float *p_humidity ,float *p_temperature) {const float C1=-4.0; // 12位濕度精度 修正公式const float C2=+0.0405; // 12位濕度精度 修正公式const float C3=-0.0000028; // 12位濕度精度 修正公式const float T1=+0.01; // 14位溫度精度 5V條件 修正公式const float T2=+0.00008; // 14位溫度精度 5V條件 修正公式float rh=*p_humidity; // rh: 12位 濕度float t=*p_temperature; // t: 14位 溫度float rh_lin; // rh_lin: 濕度 linear值float rh_true; // rh_true: 濕度 ture值float t_C; // t_C : 溫度 ℃t_C=t*0.01 - 40; //補償溫度rh_lin=C3*rh*rh + C2*rh + C1; //相對濕度非線性補償rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //相對濕度對于溫度依賴性補償*p_temperature=t_C; //返回溫度結果*p_humidity=rh_true; //返回濕度結果 }/*********************************************************/ // 溫度校正 /*********************************************************/ uchar TempCorrect(int temp) {if(temp<0) temp=0;if(temp>970) temp=970;if(temp>235) temp=temp+10;if(temp>555) temp=temp+10;if(temp>875) temp=temp+10;temp=(temp%1000)/10;return temp; }/*********************************************************/ // 濕度校正 /*********************************************************/ uchar HumiCorrect(uint humi) {if(humi>999) humi=999;if((humi>490)&&(humi<951)) humi=humi-10;humi=(humi%1000)/10;return humi; }/*********************************************************/ // 讀取SHT11的溫濕度數據 /*********************************************************/ void ReadShtData() {value humi_val,temp_val; // 定義兩個共同體,一個用于濕度,一個用于溫度uchar error; // 用于檢驗是否出現錯誤uchar checksum; // CRCuint temp1,humi1; // 臨時讀取到的溫濕度數據 error=0; //初始化error=0,即沒有錯誤error+=ShtMeasure((unsigned char*)&temp_val.i,&checksum,1); //溫度測量error+=ShtMeasure((unsigned char*)&humi_val.i,&checksum,2); //濕度測量if(error!=0) //如果發生錯誤,系統復位ShtConnectReset(); else{humi_val.f=(float)humi_val.i; //轉換為浮點數temp_val.f=(float)temp_val.i; //轉換為浮點數CalcSHT11(&humi_val.f,&temp_val.f); //修正相對濕度及溫度temp1=temp_val.f*10;temp=TempCorrect(temp1);humi1=humi_val.f*10-50;humi=HumiCorrect(humi1);}}主函數
/******************************************************** 主函數 ********************************************************/ void main(void) {LcdInit(); // 液晶功能初始化ShtConnectReset(); // 啟動連接復位LcdGotoXY(0,0); // 第0行的顯示內容LcdPrintStr(" my designer ");LcdGotoXY(1,0); // 第1行的顯示內容LcdPrintStr("H: %RH S: ");LcdGotoXY(1,4); // 溫度單位攝氏度上面的圓圈符號while(1){CheckKey(); //按鍵采集處理DelayMs(5);later++;if(later>=50){ReadShtData(); // 檢測溫濕度數據humi = humi+2;//補償// LcdGotoXY(1,2); // 定位到要顯示溫度的地方// LcdPrintNum(temp); // 顯示溫度值}LcdGotoXY(1,2); // 定位到要顯示濕度的地方LcdPrintNum(humi); // 顯示濕度值LcdGotoXY(1,10); // 定位到要顯示濕度的地方LcdPrintNum(setH); // 顯示濕度值LcdGotoXY(1,14);LcdWriteData(yeweiFlag); if((yeweiG == 1)&&(yeweiD == 1))//上下液位都無有水 低于低液位){buzzer = 0;//蜂鳴器報警 led_gre =1 ; //不亮 }else{buzzer = 1; //不報警if(humi< setH) //小于閾值{led_gre = 0; //綠燈亮}else{led_gre =1 ; //不亮}}if((yeweiG == 0)&&(yeweiD == 0))//上下液位有水{yeweiFlag = 'H';led_red = 0 ; led_blu =1;led_yel =1; //紅燈亮 }else if((yeweiG == 1)&&(yeweiD == 0))//只有低液位有水{yeweiFlag = 'N';led_red = 1 ; led_blu =0;led_yel =1; //藍燈亮 }else if((yeweiG == 1)&&(yeweiD == 1))//上下液位都無有水 低于低液位{yeweiFlag = 'L';led_red = 1 ; led_blu =1;led_yel =0; //藍燈亮 }else if((yeweiG == 0)&&(yeweiD == 1)) //異常現象 只有高液位有水{yeweiFlag = 'E';led_red = 1 ; led_blu =1;led_yel =1; //都不亮}// Buzzer_P=0; // DelayMs(100); // Buzzer_P=1; // DelayMs(100);} }總結
以上是生活随笔為你收集整理的基于51单片机的智能加湿器控制proteus仿真系统设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Idea SpringBoot工程提示
- 下一篇: k8s集群部署方式(kubeadm方式安