一、系統方案 本設計采用STC89C52作為主控制器,瓦斯傳感器、PM2.5傳感器采集數據值送到ADC0832轉換,送到單片機處理,液晶1602顯示對應測量值,溫度DS18B20采集溫度值,送到液晶顯示,風速傳感器采集風速,送到ADC0832轉換,送到單片機處理對應測量值,按鍵設置報警閥值,測量值超過設設定閥值,蜂鳴器報警。
1.png (6.08 KB, 下載次數: 43)
下載附件
2023-7-31 14:56 上傳
二、硬件設計 原理圖如下:
2.png (89.15 KB, 下載次數: 51)
下載附件
2023-7-31 14:56 上傳
三、單片機軟件設計 1、首先是系統初始化:
Lcd1602_Init(); //LCD1602初始化 Delay_function(50); //延時50ms lcd1602_clean(); //清屏 Delay_function(50); //延時50ms Ds18b20_Init(); //DS18B20初始化 Delay_function(50); //延時50ms 2、液晶顯示程序 /********************************** 包含頭文件 **********************************/ #include "lcd1602.h"
/********************************** 函數定義 **********************************/ /**** *******1602檢測忙函數 *****/ void lcd1602_check_busy() { P0=0xff; do { LCD1602_RS=0; LCD1602_RW=1; LCD1602_E=0; LCD1602_E=1; } while(LCD1602_BUSY==1); LCD1602_E=0; }
/**** *******1602寫數據忙函數 *****/ void lcd1602_write_date(uchar date) { lcd1602_check_busy(); LCD1602_E=0; LCD1602_PORT=date; LCD1602_RS=1; LCD1602_RW=0; LCD1602_E=1; LCD1602_E=0; }
/**** *******1602寫命令函數 *****/ void lcd1602_write_com(uchar com) { lcd1602_check_busy(); LCD1602_E=0; LCD1602_PORT=com; LCD1602_RS=0; LCD1602_RW=0; LCD1602_E=1; LCD1602_E=0; }
/**** *******LCD1602初始化函數 *****/ void Lcd1602_Init() { lcd1602_write_com(0x38); lcd1602_write_com(0x0c); lcd1602_write_com(0x06); lcd1602_write_com(0x01); }
/**** *******LCD1602顯示字符串函數 *******參量定義: hang:輸入顯示行數 1 第一行 2 第二行 ******* add:偏移量,0-15 ******* dat:所要顯示的字符串,輸入格式 " " *****/ void lcd1602_display_str(uchar hang, uchar add, uchar *dat) { if(hang==1) lcd1602_write_com(0x80+add); //第一行 else lcd1602_write_com(0x80+0x40+add); //第二行
while(*dat != '\0') { lcd1602_write_date(*dat++); } }
/**** *******LCD1602清屏函數 *****/ void lcd1602_clean() { lcd1602_display_str(1,0," "); lcd1602_display_str(2,0," "); }
/**** *******LCD1602顯示數字函數(最大4位) *******參量定義: hang:輸入顯示行數 1 第一行 2 第二行 ******* add:偏移量,0-15 ******* num:所要顯示的數據,最大4位 *****/ void lcd1602_display_num(uchar hang, uchar add, uint num) { if(hang==1) lcd1602_write_com(0x80+add); //第一行 else lcd1602_write_com(0x80+0x40+add); //第二行
if(num > 999) lcd1602_write_date(num/1000%10+48); //千 if(num > 99) lcd1602_write_date(num/100%10+48); //百 if(num > 9) lcd1602_write_date(num/10%10+48); //十 lcd1602_write_date(num/1%10+48); //個 lcd1602_write_date(' '); lcd1602_write_date(' '); lcd1602_write_date(' '); }
/**** *******LCD1602顯示溫度函數(顯示格式:**.*℃) *******參量定義: hang:輸入顯示行數 1 第一行 2 第二行 ******* add:偏移量,0-15 ******* temp:所要顯示的溫度 *****/ void lcd1602_display_temp(uchar hang, uchar add,uint temp) { if(hang==1) lcd1602_write_com(0x80+add); //第一行 else lcd1602_write_com(0x80+0x40+add); //第二行
lcd1602_write_date(temp/100%10+48); lcd1602_write_date(temp/10%10+48); lcd1602_write_date('.'); lcd1602_write_date(temp/1%10+48); lcd1602_write_date(0xdf); //顯示溫度的小圓圈符號,0xdf是液晶屏字符庫的該符號地址碼 lcd1602_write_date(0x43); //顯示"C"符號,0x43是液晶屏字符庫里大寫C的地址碼 }
/**** *******LCD1602顯示風速(顯示格式:**.*m/s) *******參量定義: hang:輸入顯示行數 1 第一行 2 第二行 ******* add:偏移量,0-15 ******* wind:所要顯示的風速 *****/ void lcd1602_display_wind(uchar hang, uchar add,uint wind) { if(hang==1) lcd1602_write_com(0x80+add); //第一行 else lcd1602_write_com(0x80+0x40+add); //第二行
lcd1602_write_date(wind/100%10+48); lcd1602_write_date(wind/10%10+48); lcd1602_write_date('.'); lcd1602_write_date(wind/1%10+48); lcd1602_write_date('m'); lcd1602_write_date('/'); lcd1602_write_date('s'); }
/**** *******LCD1602顯示氣體濃度(顯示格式:000ppm) *******參量定義: hang:輸入顯示行數 1 第一行 2 第二行 ******* add:偏移量,0-15 ******* gas_value:所要顯示的氣體濃度 *****/ void lcd1602_display_gas(uchar hang, uchar add,uint gas_value) { if(hang==1) lcd1602_write_com(0x80+add); //第一行 else lcd1602_write_com(0x80+0x40+add); //第二行
if(gas_value > 999) lcd1602_write_date(gas_value/1000%10+48); if(gas_value > 99) lcd1602_write_date(gas_value/100%10+48); if(gas_value > 9) lcd1602_write_date(gas_value/10%10+48); lcd1602_write_date(gas_value/1%10+48); lcd1602_write_date('p'); lcd1602_write_date('p'); lcd1602_write_date('m'); lcd1602_write_date(' '); lcd1602_write_date(' '); lcd1602_write_date(' '); }
/**** *******LCD1602顯示PM2.5(顯示格式:000ug/m3) *******參量定義: hang:輸入顯示行數 1 第一行 2 第二行 ******* add:偏移量,0-15 ******* pm25_value:所要顯示的PM2.5 *****/ void lcd1602_display_pm25(uchar hang, uchar add,uint pm25_value) { if(hang==1) lcd1602_write_com(0x80+add); //第一行 else lcd1602_write_com(0x80+0x40+add); //第二行
if(pm25_value > 999) lcd1602_write_date(pm25_value/1000%10+48); if(pm25_value > 99) lcd1602_write_date(pm25_value/100%10+48); if(pm25_value >= 9) lcd1602_write_date(pm25_value/10%10+48); lcd1602_write_date(pm25_value/1%10+48); lcd1602_write_date('u'); lcd1602_write_date('g'); lcd1602_write_date('/'); lcd1602_write_date('m'); lcd1602_write_date('3'); lcd1602_write_date(' '); }
3、按鍵檢測程序 /**** *******按鍵函數 *****/ void Key_function(void) { key_num = Chiclet_Keyboard_Scan(0); //按鍵掃描 if(key_num != 0) //有按鍵按下 { switch(key_num) { case 1: //按鍵1,切換界面 flag_display++; if(flag_display >= 6) flag_display = 0;
lcd1602_clean(); break;
case 2: //按鍵2,不同界面有不同功能 switch(flag_display) { case 0: //界面0,切換測量界面 flag_meas_display++; if(flag_meas_display >= 2) flag_meas_display = 0;
lcd1602_clean(); break;
case 1: //界面1,溫度最大值+1 if(temp_max < 99) temp_max++; break;
case 2: //界面2,溫度最小值+1 if(temp_min < temp_max-1) temp_min++; break;
case 3: //界面3,風速最大值+1 if(wind_max < 99) wind_max++; break;
case 4: //界面4,瓦斯最大值+1 if(gas_max < 500) gas_max++; break;
case 5: //界面5,PM2.5最大值+1 if(pm25_max < 500) pm25_max++; break;
default: break; } break;
case 3: //按鍵3,不同界面有不同功能 switch(flag_display) { case 1: //界面1,溫度最大值-1 if(temp_max > temp_min+1) temp_max--; break;
case 2: //界面2,溫度最小值-1 if(temp_min > 0) temp_min--; break;
case 3: //界面3,風速最大值-1 if(wind_max > 0) wind_max--; break;
case 4: //界面4,瓦斯最大值-1 if(gas_max > 0) gas_max--; break;
case 5: //界面5,PM2.5最大值-1 if(pm25_max > 0) pm25_max--; break;
default: break; } break;
default: break; } } } 4、核心算法程序 void Manage_function(void) { if(flag_display == 0) //界面0,即測量界面 { if(temp_value > temp_max*10 || temp_value < temp_min*10 || wind_value > wind_max*10 || gas_value > gas_max || pm25_value > pm25_max) //測量值不在設置的閾值之內,進行聲光報警 { if(time_num % 10 == 0) { LED = ~LED; BEEP = ~BEEP; } } else //測量值在設置的閾值之內,不進行聲光報警 { LED = 1; BEEP = 1; } } else //其他界面,即設置界面 { LED = 1; BEEP = 1; } }
四、proteus仿真設計 Proteus軟件是一款應用比較廣泛的工具,它可以在沒有硬件平臺的基礎上通過自身的軟件仿真出硬件平臺的運行情況,這樣就可以通過軟件仿真來驗證我們設計的方案有沒有問題,如果有問題,可以重新選擇器件,連接器件,直到達到我們設定的目的,避免我們搭建實物的時候,如果當初選擇的方案有問題,我們器件都已經焊接好了,再去卸載下去,再去焊接新的方案的器件,測試,這樣會浪費人力和物力,也給開發者帶來一定困惑,Proteus仿真軟件就很好的解決這個問題,我們在設計之初,就使用該軟件進行模擬仿真,測試,選擇滿足我們設計的最優方案。最后根據測試沒問題的仿真圖紙,焊接實物,調試,最終完成本設計的作品。
3.png (95.75 KB, 下載次數: 51)
下載附件
2023-7-31 14:56 上傳
|