久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5352|回復: 7
打印 上一主題 下一主題
收起左側

基于51單片機的火災報警器設計

  [復制鏈接]
跳轉到指定樓層
樓主
ID:367198 發表于 2019-6-15 16:59 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本設計采用ADC0832對火焰傳感器和煙霧傳感器獲取到的數據進行轉采集,并通過單片機將采集到的數據和設定值進行比較,從而決定是否報警。
各個報警值都可通過按鍵進行設置,各數據都是用LCD1602液晶進行顯示的,簡單易懂。

火災報警器的原理圖如下:

部分程序如下:
#include <REGX51.H>      //調用51單片機頭文件
#include <Define.c>      //調用定義變量的C文件
#include <DS18B20.c>  //調用DS18B20驅動C文件
#include <ADC.c>      //調用ADCO832驅動C文件
#include <LCD1602.c>  //調用LCD1602顯示屏的驅動C文件
#include <display.c>  //調用各種模式的顯示C文件
#include <key.c>      //調用按鍵C文件,其中包含關于各按鍵的函數
/***************定時器0中斷初始化函數****************/
void Timer0_Init(void) //使用定時器中斷0
{
    TMOD = 0x01;//使用模式0
    TH0 = (65536 - 2000) / 256;//定時器裝入初始值2ms
    TL0 = (65536 - 2000) % 256;
    ET0 = 1; //定時器0初始化
    TR0 = 1;
    EA = 1;    //總中斷
}
/***************定時器1中斷初始化函數****************/
void Timer1_Init()      //使用定時器中斷1
{
    TMOD |= 0x10;             //使用模式1
    TH1 = (65536-2000)/256;    //定時器裝入初始值2ms
    TL1 = (65536-2000)%256;
    ET1 = 1;//定時器1初始化
    TR1 = 1;
    EA = 1;  //總中斷
}
/***************定時器0中斷服務函數****************/
void Timer0_isr(void)interrupt 1      
{
    TH0 = (65536 - 2000) / 256;      //定時器裝入初始值2ms
    TL0 = (65536 - 2000) % 256;
    cp++;
    if(cp >= 100)                                                                     
    {
        temp_num = Read_Temperature();//獲取實時溫度                                                   
        cp = 0;                                                
    }
    key();    //調用key.c中的按鍵函數     
}
/***************定時器1中斷服務函數****************/
void time1_isr(void)interrupt 3
{
    TH1=(65536-2000)/256;         //定時器裝入初始值2ms
    TL1=(65536-2000)%256;
    cp1++;
    if(cp1 >= 100)
    {
        AD_smok = (GetAD0832(0)*100)/255;      //獲取煙霧濃度
    //*由于傳感器的AD輸出的特殊原因,這里用255減去輸出值以遍顯示的時候可以從0%到100%增加*//
        AD_fire = ((255 - GetAD0832(1))*100)/255;       //獲取火光亮度,        
        cp1 = 0;
    }
}
void main(void)
{   
    Init_LCD1602();     //LCD1602初始化
    Timer0_Init();     //定時器0初始化
    Timer1_Init();     //定時器1初始化
    LED1 = 0;    //關閉LED1
    LED2 = 0;    //關閉LED2
    LED3 = 0;    //關閉LED3
   
    while(1)
    {
        exchange();        //將各變量轉換為十進制進行顯示
        if(dis_mode == 0)display0();     //正常顯示
        if(dis_mode == 1)display1();     //進入修改界面   
        if(temp_num >=  Temp_alam)LED1 = 1;      //當溫度超過警報值時,打開紅色的LED
        else LED1 = 0;
        if(AD_smok >= S_alam)LED2 = 1;      //當煙霧濃度超過警報值時,打開黃色的LED
        else LED2 = 0;
        if(AD_fire >= F_alam)LED3 = 1;    //當火光亮度超過警報值時,打開藍色的LED
        else LED3 = 0;
        if((AD_fire >= F_alam)&&(AD_smok >= S_alam))Beep = 0;    //當檢測到的三個值中有兩個超過警報值,則認為有火災發生,啟動聲音報警      
        if((AD_fire >= F_alam)&&(temp_num >= Temp_alam))Beep = 0;
        if((temp_num >= Temp_alam)&&(AD_smok >= S_alam))Beep = 0;
        if((AD_fire < F_alam)&&(AD_smok < S_alam)&&(temp_num < Temp_alam))Beep = 1;     //當三個值都降到警報值以下時,聲音報警關閉
    }
}



/********初始化函數********/
void Init_DS18B20(void)                                            //基本操作函數1
{
    unsigned char x = 255;
    DQ = 1;                                                        //先讓DQ置1
    DQ = 0;                                                        //單片機將DQ拉低
    delay(80);                                                    //延時480-960us
    DQ = 1;                                                        //釋放總線
    while(DQ && x--);                                            //等待返回的低電平響應 如果沒有響應,則做適量延時自動往下執行
    delay(20);
}
/********從DS18B20中讀一個字節********/
unsigned char Read_OneChar(void)    //DS18B20開始發送RAM數據依次從0~8字節,且低位在前                                    //基本操作函數2
{
    unsigned char i = 0;
    unsigned char dat = 0;
    for (i=8;i>0;i--)
    {
          DQ = 0;                                                    //發送啟動信號
          dat >>= 1;                                          
          DQ = 1;                                                    //釋放總線
          if(DQ)                                                    //判斷總線是否為高電平
          dat |= 0x80;                                            //如果是高電平,則把dat的最高位置1,如果不是,默認置0
          delay(10);
    }
    return(dat);
}
/********向18B20中寫一個字節********/
void Write_OneChar(unsigned char dat)                                    //基本操作函數3
{
    unsigned char i=0;
    for (i=8; i>0; i--)
    {
        DQ = 0;
        DQ = dat & 0x01;    //先寫入數據的最低位                                    //取dat的最低位
        delay(10);
        DQ = 1;
        dat >>= 1;            //再依次寫入數據的低二位,低三位
    }
    delay(8);
}
/********讀取溫度********/
unsigned char a,b,c;
unsigned char Read_Temperature(void)                                    //應用操作函數1
{
    unsigned char t;
    Init_DS18B20();
    Write_OneChar(0xcc);    // 1100 1100  主機寫CCH跳過ROM操作                                    // 跳過讀序號列號的操作
    Write_OneChar(0x44);    // 0100 0100                                    // 啟動溫度轉換
    Init_DS18B20();
    Write_OneChar(0xcc);    // 1100 1100                                    //跳過讀序號列號的操作
    Write_OneChar(0xbe);    // 1011    1110   主機寫BBH讀出RAM數據                                //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
    a = Read_OneChar();                                            //讀取溫度值低位
    b = Read_OneChar();                                            //讀取溫度值高位
    c = 0x0f & a;            // 0000 1111 &                                     //得到小數部分
    a = a >> 4;                                                    //低位右移4位
    b = b << 4;                                                    //高位左移4位
    t = a | b;                                                    //得到8位溫度的整數部分,最高1位為符號位
    return(t);
}


#define LCD1602_DB P0    //LCD1602數據總線
/*=================================================
*函數名稱:Read_Busy
*函數功能:判斷1602液晶忙,并等待
=================================================*/
void Read_Busy()
{
    uchar busy;
    LCD1602_DB = 0xff;//復位數據總線
    LCD1602_RS = 0;      //拉低RS
    LCD1602_RW = 1;      //拉高RW讀
    do
    {
        LCD1602_EN = 1;//使能EN
        busy = LCD1602_DB;//讀回數據
        LCD1602_EN = 0;     //拉低使能以便于下一次產生上升沿
    }while(busy & 0x80); //判斷狀態字BIT7位是否為1,為1則表示忙,程序等待
}
/*=================================================
*函數名稱:LCD1602_Write_Cmd
*函數功能:寫LCD1602命令
*調用:Read_Busy();
*輸入:cmd:要寫的命令
=================================================*/
void LCD1602_Write_Cmd(uchar cmd)
{
    Read_Busy();     //判斷忙,忙則等待
    LCD1602_RS = 0;
    LCD1602_RW = 0;    //拉低RS、RW操作時序情況1602課件下中文使用說明基本操作時序章節
    LCD1602_DB = cmd;//寫入命令
    LCD1602_EN = 1;     //拉高使能端 數據被傳輸到LCD1602內
    LCD1602_EN = 0;     //拉低使能以便于下一次產生上升沿
}
/*=================================================
*函數名稱:LCD1602_Write_Dat
*函數功能:寫LCD1602數據
*調用:Read_Busy();
*輸入:dat:需要寫入的數據
=================================================*/
void LCD1602_Write_Dat(uchar dat)
{
    Read_Busy();
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    LCD1602_DB = dat;
    LCD1602_EN = 1;
    LCD1602_EN = 0;
}
/*=================================================
*函數名稱:LCD1602_Dis_OneChar
*函數功能:在指定位置顯示一個字符
*調用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();   
*輸入:x:要顯示的橫坐標取值0-40,y:要顯示的行坐標取值0-1(0為第一行,1為第二行)
        dat:需要顯示的數據以ASCLL形式顯示
=================================================*/
void LCD1602_Dis_OneChar(uchar x, uchar y,uchar dat)
{
    if(y)    x |= 0x40;
    x |= 0x80;
    LCD1602_Write_Cmd(x);
    LCD1602_Write_Dat(dat + 0x30);
            
}
/*=================================================
*函數名稱:LCD1602_Dis_Str
*函數功能:在指定位置顯示字符串
*調用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();
*輸入:x:要顯示的橫坐標取值0-40,y:要顯示的行坐標取值0-1(0為第一行,1為第二行)
        *str:需要顯示的字符串
=================================================*/
void LCD1602_Dis_Str(uchar x, uchar y, uchar *str)
{
    if(y) x |= 0x40;
    x |= 0x80;
    LCD1602_Write_Cmd(x);
    while(*str != '\0')
    {
        LCD1602_Write_Dat(*str++);
    }
}
/*=================================================
*函數名稱:Init_LCD1602
*函數功能:1602初始化
*調用:    LCD1602_Write_Cmd();
=================================================*/
void Init_LCD1602()
{
    LCD1602_Write_Cmd(0x38); //    設置16*2顯示,5*7點陣,8位數據接口
    LCD1602_Write_Cmd(0x0c); //開顯示
    LCD1602_Write_Cmd(0x06); //讀寫一字節后地址指針加1
    LCD1602_Write_Cmd(0x01); //清除顯示
}



/***********按鍵函數*************/
void key(void)
{
    if(key1 == 0)
    {
        delay(200);      //按鍵消抖
        if(key1 == 0)
        {
            if(dis_mode == 0)
            {
                dis_mode = 1;
                Temp_set = Temp_alam;        //設置溫度報警值
                Fire_set = F_alam;            //設置火光報警值
                Smok_set = S_alam;            //設置煙霧報警值
            }
            else if(dis_mode == 1)
            {
                set_mode++;               //設置標志位加
                if(set_mode >= 4)set_mode = 0;
                        
            }            
        }
        while(key1 == 0);
    }

    if(key2 == 0)
    {
        delay(200);            
        if(key2 == 0)
        {
            if((dis_mode == 1)&&(set_mode == 1))  //警報值加
            Temp_set++;
            if((dis_mode == 1)&&(set_mode == 2))
            Fire_set++;
            if((dis_mode == 1)&&(set_mode == 3))
            Smok_set++;
        }
        while(key2 == 0);
    }

    if(key3 == 0)
    {
        delay(200);               //按鍵消抖
        if(key3 == 0)
        {
            if((dis_mode == 1)&&(set_mode == 1))  //警報值減
            Temp_set--;
            if((dis_mode == 1)&&(set_mode == 2))
            Fire_set--;
            if((dis_mode == 1)&&(set_mode == 3))
            Smok_set--;
        }
        while(key3 == 0);
    }

    if(key4 == 0)
    {
        delay(200);               //按鍵消抖
        if(key4 == 0)
        {
            dis_mode = 0;       //將顯示標志位置0
            set_mode = 0;       //將設置標志位置0
            Temp_alam = Temp_set;  //設置的警報值生效
            F_alam = Fire_set;
            S_alam = Smok_set;
        }
        while(key4 == 0);
    }
    if(Temp_set >= 255)Temp_set = 255;         //上限值
    if(Fire_set >= 100)Fire_set = 100;         //上限值
    if(Smok_set >= 100)Smok_set = 100;         //上限值
    if(Temp_set <= 0)Temp_set = 0;             //下限值
    if(Fire_set <= 0)Fire_set = 0;             //下限值
    if(Smok_set <= 0)Smok_set = 0;             //下限值
}



uchar GetAD0832(uint Channel)
{
    uchar i=0,Data1 =0,Data2 = 0;
    AD0832_CLK = 0 ; //時鐘置低平
    AD0832_DI = 1 ; //開始信號為高電平
    AD0832_CS = 0 ; //片選信號置低,啟動AD轉換芯片
    AD0832_CLK = 1 ; //輸入開始信號(構成一個正脈沖),時鐘上升沿,輸入開始信號
    AD0832_CLK = 0 ; //時鐘下降沿
    //模擬信號輸入模式選擇(1:單模信號,0:雙模差分信號)
    AD0832_DI = 1 ;
    AD0832_CLK = 1 ; //時鐘上升沿,輸入開始信號
    AD0832_CLK = 0 ; //時鐘下降沿
    //模擬信號輸入通道選擇(1:通道CH1,0:通道CH0)
    AD0832_DI = Channel ; //選擇通道0
    AD0832_CLK = 1 ; //時鐘上升沿,輸入開始信號
    AD0832_CLK = 0 ; //時鐘下降沿
   
    AD0832_DI = 1 ; //數據線置高,準備接收數據
    for(i=0;i<8;i++) //從高位移入數據
      {
       AD0832_CLK = 1 ;
    AD0832_CLK = 0 ; //時鐘下降沿,AD0832輸出數據,高位(MSB)先
      Data1 = Data1<<1;
    if(AD0832_DI == 1)
        {Data1 = Data1 | 0x01;} //數據左移位,補0 ,如果數據為“1”,移入1, 如果數據為“0”,移入0,
   }
    for(i=0;i<8;i++) //從低位移入數據
    {
        Data2 = Data2>>1;
        if(AD0832_DI == 1)
            {  Data2 = Data2 | 0x80;} //數據右移位,補0,如果數據為“1”,移入1如果數據為“0”,移入0,
               AD0832_CLK = 1 ;
               AD0832_CLK = 0 ; //時鐘下降沿,AD0832輸出數據,高位(MSB)先
    }
        //數據線置高,釋放總線,完成一次轉換
    AD0832_CLK = 1 ;
    AD0832_DI = 1 ;
    AD0832_CS = 1 ;
    return (Data1==Data2)?Data1:0; //   如果相等輸出data1  or  0
}



本設計包含程序、仿真已及PCB設計,拿到之后可以直接使用。


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

使用道具 舉報

沙發
ID:1 發表于 2019-6-15 19:50 | 只看該作者
本帖需要重新編輯補全電路原理圖,源碼,詳細說明與圖片即可獲得100+黑幣(帖子下方有編輯按鈕)
回復

使用道具 舉報

板凳
ID:645035 發表于 2019-11-19 20:04 | 只看該作者
666  有完整代碼嗎
回復

使用道具 舉報

地板
ID:736486 發表于 2020-4-23 23:31 | 只看該作者
尚子義 發表于 2019-11-19 20:04
666  有完整代碼嗎

不完整嗎?
回復

使用道具 舉報

5#
ID:736486 發表于 2020-4-23 23:33 | 只看該作者
想看完整代碼
回復

使用道具 舉報

6#
ID:736486 發表于 2020-4-24 22:15 | 只看該作者
有錯誤的
回復

使用道具 舉報

7#
ID:832989 發表于 2021-1-4 23:58 來自手機 | 只看該作者
有原理圖嘛
回復

使用道具 舉報

8#
ID:1074288 發表于 2023-4-26 20:27 | 只看該作者
有溫度傳感器嗎
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲 中文 欧美 日韩 在线观看 | 中文字幕精品视频 | 国产一级黄色网 | 久久久123| 国产欧美在线视频 | 美女爽到呻吟久久久久 | 国产91一区 | 亚洲综合一区二区三区 | 高清一区二区视频 | 福利视频亚洲 | 狠狠干天天干 | 国产日韩欧美在线观看 | 日韩精品一区二区久久 | 成人免费视频网站在线看 | 成人在线播放 | 久久久久成人精品 | 亚洲啊v在线 | 久久精品亚洲精品国产欧美 | 成年视频在线观看 | 中文二区| 婷婷综合五月天 | 国产在线精品一区二区 | 国产精品99久久久久久久vr | 久久久久国产精品一区二区 | 人人鲁人人莫人人爱精品 | 国产亚洲精品久久午夜玫瑰园 | 国产综合久久久久久鬼色 | 日韩在线欧美 | 国产一区二区 | 综合久久亚洲 | 九一精品 | 97色免费视频 | 精品国产一区久久 | 久久国产精品一区二区三区 | 国产精品久久久久久婷婷天堂 | 91精品国产综合久久国产大片 | 特级丰满少妇一级aaaa爱毛片 | 亚洲精品一区二区网址 | 日本字幕在线观看 | 成人欧美一区二区三区黑人孕妇 | 亚洲成人免费视频在线观看 |