找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1532|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

基于單片機瓦斯氣體PM2.5溫度風速檢測報警系統(tǒng)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:190577 發(fā)表于 2023-7-31 14:57 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
一、系統(tǒng)方案
本設(shè)計采用STC89C52作為主控制器,瓦斯傳感器、PM2.5傳感器采集數(shù)據(jù)值送到ADC0832轉(zhuǎn)換,送到單片機處理,液晶1602顯示對應(yīng)測量值,溫度DS18B20采集溫度值,送到液晶顯示,風速傳感器采集風速,送到ADC0832轉(zhuǎn)換,送到單片機處理對應(yīng)測量值,按鍵設(shè)置報警閥值,測量值超過設(shè)設(shè)定閥值,蜂鳴器報警。



二、硬件設(shè)計
原理圖如下:

三、單片機軟件設(shè)計
1、首先是系統(tǒng)初始化:

Lcd1602_Init();                                                                                         //LCD1602初始化
        Delay_function(50);                                                                        //延時50ms
        lcd1602_clean();                                                                                //清屏
        Delay_function(50);                                                                        //延時50ms
        Ds18b20_Init();                                                                                        //DS18B20初始化
        Delay_function(50);                                                                        //延時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 != '\0')
        {
                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);                //個
        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顯示風速(顯示格式:**.*m/s)
*******參量定義:        hang:輸入顯示行數(shù)  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:輸入顯示行數(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,風速最大值+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)                //測量值不在設(shè)置的閾值之內(nèi),進行聲光報警
                {
                        if(time_num % 10 == 0)
                        {
                                LED = ~LED;
                                BEEP = ~BEEP;
                        }
                }
                else                                                                                                                                                        //測量值在設(shè)置的閾值之內(nèi),不進行聲光報警        
                {
                        LED = 1;
                        BEEP = 1;
                }
        }
        else                                                                                                                                                                //其他界面,即設(shè)置界面
        {
                LED = 1;
                BEEP = 1;
        }
}

四、proteus仿真設(shè)計
Proteus軟件是一款應(yīng)用比較廣泛的工具,它可以在沒有硬件平臺的基礎(chǔ)上通過自身的軟件仿真出硬件平臺的運行情況,這樣就可以通過軟件仿真來驗證我們設(shè)計的方案有沒有問題,如果有問題,可以重新選擇器件,連接器件,直到達到我們設(shè)定的目的,避免我們搭建實物的時候,如果當初選擇的方案有問題,我們器件都已經(jīng)焊接好了,再去卸載下去,再去焊接新的方案的器件,測試,這樣會浪費人力和物力,也給開發(fā)者帶來一定困惑,Proteus仿真軟件就很好的解決這個問題,我們在設(shè)計之初,就使用該軟件進行模擬仿真,測試,選擇滿足我們設(shè)計的最優(yōu)方案。最后根據(jù)測試沒問題的仿真圖紙,焊接實物,調(diào)試,最終完成本設(shè)計的作品。

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:432633 發(fā)表于 2023-10-20 14:19 | 只看該作者
代碼和仿真圖上傳下呀
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表