一、系統(tǒng)方案
本設(shè)計(jì)采用STC89C52作為主控制器,瓦斯傳感器、PM2.5傳感器采集數(shù)據(jù)值送到ADC0832轉(zhuǎn)換,送到單片機(jī)處理,液晶1602顯示對應(yīng)測量值,溫度DS18B20采集溫度值,送到液晶顯示,風(fēng)速傳感器采集風(fēng)速,送到ADC0832轉(zhuǎn)換,送到單片機(jī)處理對應(yīng)測量值,按鍵設(shè)置報(bào)警閥值,測量值超過設(shè)設(shè)定閥值,蜂鳴器報(bào)警。
二、硬件設(shè)計(jì)
原理圖如下:
三、單片機(jī)軟件設(shè)計(jì)
1、首先是系統(tǒng)初始化:
Lcd1602_Init(); //LCD1602初始化
Delay_function(50); //延時(shí)50ms
lcd1602_clean(); //清屏
Delay_function(50); //延時(shí)50ms
Ds18b20_Init(); //DS18B20初始化
Delay_function(50); //延時(shí)50ms
2、液晶顯示程序
/**********************************
包含頭文件
**********************************/
#include "lcd1602.h"
/**********************************
函數(shù)定義
**********************************/
/****
*******1602檢測忙函數(shù)
*****/
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寫數(shù)據(jù)忙函數(shù)
*****/
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寫命令函數(shù)
*****/
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初始化函數(shù)
*****/
void Lcd1602_Init()
{
lcd1602_write_com(0x38);
lcd1602_write_com(0x0c);
lcd1602_write_com(0x06);
lcd1602_write_com(0x01);
}
/****
*******LCD1602顯示字符串函數(shù)
*******參量定義: hang:輸入顯示行數(shù) 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 != '?')
{
lcd1602_write_date(*dat++);
}
}
/****
*******LCD1602清屏函數(shù)
*****/
void lcd1602_clean()
{
lcd1602_display_str(1,0," ");
lcd1602_display_str(2,0," ");
}
/****
*******LCD1602顯示數(shù)字函數(shù)(最大4位)
*******參量定義: hang:輸入顯示行數(shù) 1 第一行 2 第二行
******* add:偏移量,0-15
******* num:所要顯示的數(shù)據(jù),最大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); //個(gè)
lcd1602_write_date(' ');
lcd1602_write_date(' ');
lcd1602_write_date(' ');
}
/****
*******LCD1602顯示溫度函數(shù)(顯示格式:**.*℃)
*******參量定義: hang:輸入顯示行數(shù) 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顯示風(fēng)速(顯示格式:**.*m/s)
*******參量定義: hang:輸入顯示行數(shù) 1 第一行 2 第二行
******* add:偏移量,0-15
******* wind:所要顯示的風(fēng)速
*****/
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:輸入顯示行數(shù) 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:輸入顯示行數(shù) 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、按鍵檢測程序
/****
*******按鍵函數(shù)
*****/
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,風(fēng)速最大值+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,風(fēng)速最大值-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) //測量值不在設(shè)置的閾值之內(nèi),進(jìn)行聲光報(bào)警
{
if(time_num % 10 == 0)
{
LED = ~LED;
BEEP = ~BEEP;
}
}
else //測量值在設(shè)置的閾值之內(nèi),不進(jìn)行聲光報(bào)警
{
LED = 1;
BEEP = 1;
}
}
else //其他界面,即設(shè)置界面
{
LED = 1;
BEEP = 1;
}
}
四、proteus仿真設(shè)計(jì)
Proteus軟件是一款應(yīng)用比較廣泛的工具,它可以在沒有硬件平臺的基礎(chǔ)上通過自身的軟件仿真出硬件平臺的運(yùn)行情況,這樣就可以通過軟件仿真來驗(yàn)證我們設(shè)計(jì)的方案有沒有問題,如果有問題,可以重新選擇器件,連接器件,直到達(dá)到我們設(shè)定的目的,避免我們搭建實(shí)物的時(shí)候,如果當(dāng)初選擇的方案有問題,我們器件都已經(jīng)焊接好了,再去卸載下去,再去焊接新的方案的器件,測試,這樣會(huì)浪費(fèi)人力和物力,也給開發(fā)者帶來一定困惑,Proteus仿真軟件就很好的解決這個(gè)問題,我們在設(shè)計(jì)之初,就使用該軟件進(jìn)行模擬仿真,測試,選擇滿足我們設(shè)計(jì)的最優(yōu)方案。最后根據(jù)測試沒問題的仿真圖紙,焊接實(shí)物,調(diào)試,最終完成本設(shè)計(jì)的作品。
-
控制器
+關(guān)注
關(guān)注
112文章
16367瀏覽量
178115 -
報(bào)警系統(tǒng)
+關(guān)注
關(guān)注
5文章
647瀏覽量
75196 -
DS18B20
+關(guān)注
關(guān)注
10文章
779瀏覽量
80873 -
單片機(jī)
+關(guān)注
關(guān)注
0文章
216瀏覽量
16658
發(fā)布評論請先 登錄
相關(guān)推薦
評論