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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

煙霧報警器碼源 mq2和dht 11

[復制鏈接]
跳轉到指定樓層
樓主
ID:389551 發表于 2018-8-26 22:03 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
#include <reg52.h>
#include <eepom52.h>
#define uchar unsigned char
#define uint  unsigned int
#include <intrins.h>
unsigned  int  q;
//數碼管段選定義0     1    2    3    4    5  6  7   8    9  
uchar code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};  //斷碼

//數碼管位選定義
uchar code smg_we[]={0x7f,0xbf,0xdf,0xef};
//uchar code smg_we[]={0xfe,0xfd,0xfb,0xf7};

uchar dis_smg[8]  = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};
uchar smg_i = 3;    //顯示數碼管的個位數

sbit SCL=P3^4;  //SCL定義為P1口的第3位腳,連接ADC0832SCL腳
sbit DO=P3^3;  //DO定義為P1口的第4位腳,連接腳
sbit CS=P3^2;  //CS定義為P14位腳,連接ADC0832CS腳



sbit dq   = P3^5; //18b20 IO口的定義
sbit beep = P3^6;   //蜂鳴器口定義
uint temperature,s_temp ;  //溫度的變量
uchar dengji,s_dengji;     //煙物等級
uchar shoudong;            //手動報警鍵
uint huoyan;


bit flag_300ms ;
uchar key_can;   //按鍵值的變量
uchar menu_1;        //菜單設計的變量
bit flag_lj_en;   //按鍵連加使能
bit flag_lj_3_en;  //按鍵連3次連加后使能加的數就越大了
  uchar key_time,flag_value;      //用做連加的中間變量
bit key_500ms  ;

uchar flag_clock;
uchar zd_break_en,zd_break_value;   //自動退出設置界面
uchar a_a;


/***********************1ms延時函數*****************************/
void delay_1ms(uint q)
{
        uint i,j;
for(i=0;i<q;i++)   

for(j=0;j<120;j++);
}


/***********************小延時函數*****************************/
void delay_uint(uint q)
{
while(q--);
}

/******************把數據保存到單片機內部eepom中******************/
void write_eepom()
{  
SectorErase(0x2000);  
byte_write(0x2000, s_temp);
byte_write(0x2001, s_dengji);
byte_write(0x2060, a_a);
}


/******************把數據從單片機內部eepom中讀出來*****************/
void read_eepom()
{
s_temp   = byte_read(0x2000);
s_dengji = byte_read(0x2001);
a_a      = byte_read(0x2060);
}



/**************開機自檢eepom初始化*****************/
void init_eepom()
{
        read_eepom();  //先讀

if(a_a != 1)  //新的單片機初始單片機內問EEPOM  
{  
s_temp   = 50;  
s_dengji = 5;   
a_a = 1;   
write_eepom();
}
}


/***********************18b20初始化函數*****************************/
void init_18b20()
{
        bit q;
        dq = 1;    //把總線拿高
  delay_uint(1);     //15us  
        dq = 0;          //給復位脈沖
  delay_uint(80);  //750us
        dq = 1;          //把總線拿高 等待
  delay_uint(10);  //110us  
        q = dq;          //讀取18b20初始化信號
  delay_uint(20);  //200us  
        dq = 1;                 //把總線拿高 釋放總線
}


/*************寫18b20內的數據***************/
void write_18b20(uchar dat)
{
        uchar i;  
        for(i=0;i<8;i++)  
        {      //寫數據是低位開始
   dq = 0;    //把總線拿低寫時間隙開始
    dq = dat & 0x01; //向18b20總線寫數據了
   delay_uint(5);  // 60us   
                dq = 1;    //釋放總線
   dat >>= 1;
}  


/*************讀取18b20內的數據***************/
uchar read_18b20()
{
         uchar i, value;  
         for(i=0;i<8;i++)
         {
  dq = 0;    //把總線拿低讀時間隙開始
    value >>= 1;  //讀數據是低位開始
   dq = 1;    //釋放總線
   if(dq == 1)   //開始讀寫數據
     value |= 0x80;  
         delay_uint(5);  //60us 讀一個時間隙最少要保持60us的時間
  }  
       
        return value;   //返回數據
}

/*************讀取溫度的值讀出來的是小數***************/
uint read_temp()
{  
         uint value;  
         uchar low;      //在讀取溫度的時候如果中斷的太頻繁了,就應該把中斷給關了,否則會影響到18b20的時序
  init_18b20();     //初始化18b20  
         write_18b20(0xcc);    //跳過64位ROM  
         write_18b20(0x44);    //啟動一次溫度轉換命令
  delay_uint(50);     //500us

init_18b20();     //初始化18b20
         
          write_18b20(0xcc);    //跳過64位ROM  
         write_18b20(0xbe);    //發出讀取暫存器命令
    EA = 0;
         low = read_18b20();    //讀溫度低字節
  value = read_18b20();  //讀溫度高字節
  EA = 1;  
         value <<= 8;     //把溫度的高位左移8位
  value |= low;     //把讀出的溫度低位放到value的低八位中
  value *= 0.0625;        //轉換到溫度值
   return value;     //返回讀出的溫度
  }
       
       
       
       
        /***********讀數模轉換數據********************************************************/  //請先了解ADC0832模數轉換的串行協議,再來讀本函數,主要是對應時序圖來理解,本函數是模擬0832的串行協議進行的
       //  1  0  0 通道
       //  1  1  1 通道
  unsigned char ad0832read(bit SGL,bit ODD)
         
        {  
                unsigned char i=0,value=0,value1=0;     
                SCL=0;  
                DO=1;
                CS=0;  //開始
   SCL=1;  //第一個上升沿
    SCL=0;  
                DO=SGL;   
                SCL=1;   //第二個上升沿
   SCL=0;
                DO=ODD;  
                SCL=1;     //第三個上升沿
         SCL=0;     //第三個下降沿
   DO=1;   
                for(i=0;i<8;i++)   
                {   
                        SCL=1;   
                        SCL=0; //開始從第四個下降沿接收數據
    value<<=1;   
if(DO)     
value++;      
  }
       
        for(i=0;i<8;i++)   
        {   //接收校驗數據
    value1>>=1;   
if(DO)     
value1+=0x80;   
SCL=1;   
SCL=0;  
}   
CS=1;  
SCL=1;
if(value==value1)    //與校驗數據比較,正確就返回數據,否則返回0     
        return value;
return 0;
}  




/***********************數碼顯示函數*****************************/
void display()
{  
        uchar i;  
        for(i=0;i<smg_i;i++)
{                  
        P2 = smg_we[i];     //位選
   P1 = dis_smg[i];   //段選
         delay_1ms(1);  
  P1 = 0xff;    //消隱
    P2 = 0xff;        //位選
     }
}


/*************定時器0***************/
void time_init()   
{  EA   = 1;     //開總中斷
  TMOD = 0X01;   //定時器0、定時器1工作方式1  
        ET0  = 1;    //開定時器0中斷
   TR0  = 1;    //允許定時器0定時
}


/****************按鍵處理數碼管顯示函數***************/



void key_with()
{
if(key_can == 4)   //緊急報警鍵  手動報警
  {   
if(menu_1 == 0)   
shoudong = 1;  
}  
if(key_can == 1)  //設置鍵
  {
                menu_1 ++;   
                if(menu_1 >= 3)  
                        {   
                                menu_1 = 0;  
                                }   
                                if(menu_1 == 0)   
                                        {    dis_smg[0] = smg_du[temperature % 10];  //取溫度的個位數顯示
               dis_smg[1] = smg_du[temperature / 10 % 10]; //取溫度的十位顯示
               smg_i = 3;  
}  


if(menu_1 == 1)   
                {   


                        dis_smg[0] = smg_du[s_temp % 10];            //取個位顯示
      dis_smg[1] = smg_du[s_temp / 10 % 10] ;  //取十位顯示
      dis_smg[2] = 0xbf ;   
                        dis_smg[3] = smg_du[10]; //顯示A   
                        smg_i = 4;   
}   
                        if(menu_1 == 2)   
                                {     
                                        dis_smg[0] = smg_du[s_dengji % 10];            //取個位顯示
          dis_smg[1] = 0xbf ;      
                                        dis_smg[2] = 0xbf ;   
                                        dis_smg[3] = smg_du[11]; //顯示B   
                                        smg_i = 4;  
}  
                                        }
                                       
                                        if(menu_1 == 0)  
                                                {  
                                                        if((key_can == 2) || (key_can == 3))   
                                                                shoudong = 0;          //取消手動報警
  }   
          if(menu_1 == 1)   //設置高溫報警
              {     
                                                                if(key_can == 2)   
                                                                        {   if(flag_lj_3_en == 0)     
                                                                                s_temp ++ ;  //按鍵按下未松開自動加三次
     else        
                         s_temp += 10; //按鍵按下未松開自動加三次之后每次自動加10   
                 if(s_temp > 99)  
                         s_temp = 99;  
                 dis_smg[0] = smg_du[s_temp % 10];            //取個位顯示
    dis_smg[1] = smg_du[s_temp / 10 % 10];        //取十位顯示
    dis_smg[2] = 0xbf ;   
                 dis_smg[3] = smg_du[10]; //顯示A   
                 }   
                 if(key_can == 3)  
                         {    if(flag_lj_3_en == 0)     
                                 s_temp .. ;  //按鍵按下未松開自動加三次
     else   
                         s_temp .= 10; //按鍵按下未松開自動減三次之后每次自動減10   
                 if(s_temp <= 10)     
                         s_temp = 10 ;   
                 dis_smg[0] = smg_du[s_temp % 10];            //取個位顯示
    dis_smg[1] = smg_du[s_temp / 10 % 10];  //取十位顯示
    dis_smg[2] = 0xbf;   
                 dis_smg[3] = smg_du[10]; //顯示A  
                 }  
}  
if(menu_1 == 2)   //設置低溫報警
  {   
                if(key_can == 2)  
                        {   
                                if(flag_lj_3_en == 0)
                 s_dengji ++ ;     
                                else     
                                        s_dengji ++ ;   
                                if(s_dengji >= 9)  
                                        s_dengji = 9;   
                                dis_smg[0] = smg_du[s_dengji % 10];            //取個位顯示
        dis_smg[1] = 0xbf ;     
                                dis_smg[2] = 0xbf ;   
                                dis_smg[3] = smg_du[11]; //顯示B  
                                }   
                                if(key_can == 3)  
                                        {  
                                                if(flag_lj_3_en == 0)   
                                                        s_dengji .. ;     
                                                else     
                                                        s_dengji ..;   
                                                if(s_dengji <= 1)   
                                                        s_dengji = 1;   
                                                dis_smg[0] = smg_du[s_dengji % 10];            //取個位顯示
             dis_smg[1] = 0xbf ;   
                                                dis_smg[2] = 0xbf;
                                                dis_smg[3] = smg_du[11]; //顯示B  
                                                }
}
}   






/****************獨立按鍵處理函數************************/
void key()
{
         static uchar key_new = 0,key_old = 0,key_value = 0;  
         if(key_new == 0)     
                 {         //按鍵松開的時候做松手檢測
   if((P2 & 0x0f) == 0x0f)   
                 key_value ++;


  else     
                key_value = 0;  
        if(key_value >= 5)  
                {    write_eepom();  
                        key_value = 0;  
                        key_time = 0;  
                        key_new = 1;  
                        flag_lj_en = 0;  //關閉連加使能       
                        flag_lj_3_en = 0; //關閉3秒后使能       
                        flag_value = 0;  //清零
   }  
}


else  
         {   
                 if((P2 & 0x0f) != 0x0f)
                         key_value ++;  //按鍵按下的時候
   else   
                 key_value = 0;   
         if(key_value >= 5)  
                 {    key_value = 0;   
                         key_new = 0;   
                         flag_lj_en = 1;     //連加使能
    zd_break_en = 1;    //自動退出設置界使能
    zd_break_value = 0; //自動退出設置界變量清零
   }   
}
         key_can = 20;  
         if(key_500ms == 1)
                 {   key_500ms = 0;   
                         zd_break_en = 1; //自動退出設置界使能


  zd_break_value = 0; //自動退出設置界變量清零
   key_new = 0;   
                         key_old = 1;  
                         }  
                         if((key_new == 0) && (key_old == 1))
                                 {   switch(P2 & 0x0f)   
                                         {    case 0x0e: key_can = 4;
                                                 break;    //得到k1鍵值
    case 0x0d:
                        key_can = 3; break;    //得到                                                 k2鍵值
    case 0x0b: key_can = 2; break;    //得到鍵值
    case 0x07: key_can = 1; break;    //得到k4鍵值
               
   }
}     
key_old = key_new;  
}


/****************報警函數***************/
void clock_h_l()
{
         static uchar value;  
         if((dengji >= s_dengji) || (temperature >= s_temp) || (shoudong == 1))  //報警
  {  
                value ++;   
                if(value >= 3)  
                        {   
                                value = 10;
                                beep = ~beep;   //蜂鳴器報警
   }  
}
         else  
                 {
                         if((dengji < s_dengji) && (temperature < (s_temp . 1)) && (shoudong == 0))   //取消報警
   {

  value = 0;
                 beep = 1;  
                 }
                 }
                 }  
                 void main()
                 {  
                         static uchar value;
                         temperature = read_temp();  //讀取溫度值

                         init_eepom();         //讀數據

                         time_init();    //初始化定時器

                         delay_1ms(650);   
                         while(1)  
                                 {  
                                         key();     //獨立按鍵程序

                                         if(key_can < 10)  
                                                 {   
                                                         key_with();   //按鍵按下要執行的程序

}  
temperature = read_temp();  //讀取溫度值

if(flag_300ms == 1)  
         {      
                 flag_300ms = 0;   
                 clock_h_l();   
                 dengji = ad0832read(1,0);
                 dengji = dengji * 10 / 250;  
                 huoyan = ad0832read(1,1);     
                 huoyan = 10 . huoyan * 10 / 250;   
                 if(menu_1 == 0)   
                         {   
                                 if(temperature >= 99)
temperature = 99;


if(value > 20)   
   value = 0;         
if(huoyan < 2)   
         {      
                 smg_i = 4;
     dis_smg[3]=smg_du[dengji];     //顯示煙物報警等級
      dis_smg[2]= 0xbf;             // .      
                 dis_smg[1]=smg_du[temperature/10%10]; //十位
      dis_smg[0]=smg_du[temperature%10];     //個位 ADC0832為8位ADC,數值為0~255,我們將其分開放入l_tmpdate數組中顯示
     }
                 else     
                         {   
                                 shoudong = 1;   
                                 smg_i = 4;      
                                 dis_smg[3]=0x89;  //H;        
                                 dis_smg[2]=0x89;  //H;               
                                 dis_smg[1]=0x89;  //H;      
                                 dis_smg[0]=0x89;  //H;     
                                 }   
}   
if(zd_break_en == 1) //自動退出設置界面程序
    {     zd_break_value ++;  //每300ms加一次
     if(zd_break_value > 100)   //30秒后自動退出設置界面
     {     
                         menu_1 = 0;         
                         smg_i = 3;   
                         zd_break_en = 0;
                         zd_break_value = 0;   
  }  

}  
}   
display();   //數碼管顯示函數



}
}



/*************定時器0中斷服務程序***************/
void time0_int()
interrupt 1
{   
        static uchar value;
        TH0 = 0x3c;
        TL0 = 0xb0;     // 50ms  value ++;   
        if(value % 6 == 0)  
                {   flag_300ms = 1;    //300ms  
                        value = 0;  }
                        if(flag_lj_en == 1)    //按下按鍵使能
  {  
                key_time ++;
                if(key_time >= 10) //500ms
                        {    key_time = 0;   
                                key_500ms = 1; //500ms   
                                flag_value ++;   
                                if(flag_value > 3)   
                                        {     flag_value = 10;   
                                                flag_lj_3_en = 1; //3次后1.5秒連加大些
    }   

}

}

}
















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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日日操网站 | 成人亚洲性情网站www在线观看 | 大伊人久久| 精品无码久久久久国产 | 99re热精品视频 | 国产精品99免费视频 | 欧美精品一区二区三区在线播放 | 久久日本| 欧美一级久久久猛烈a大片 日韩av免费在线观看 | 男人天堂网址 | 亚洲日本中文 | 亚洲成人精品在线观看 | 免费成人国产 | 91在线观看 | 男人影音| 亚洲成人一区 | 中文字幕亚洲欧美 | 91精品中文字幕一区二区三区 | 999观看免费高清www | 国产成人福利 | 狠狠久| 欧美一级做性受免费大片免费 | 精品成人 | 国产精品一区二区电影 | 久久精品久久久久久 | 精品综合 | 日韩精品中文字幕一区二区三区 | 欧美中文字幕 | 亚洲欧美综合 | 国产成人精品久久 | 在线欧美日韩 | 操射视频 | 91视频观看 | 精品久久久久久亚洲精品 | 99视频免费 | 免费久| 中文字幕欧美日韩一区 | 国产精品我不卡 | 久久69精品久久久久久久电影好 | 国产伦精品 | 成人二区 |