加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入

51單片機(jī)智能家居環(huán)境檢測 煙霧溫度GSM短信提示報警器(原理圖+程序+仿真+PCB)

08/01 09:30
3679
服務(wù)支持:
技術(shù)交流群

完成交易后在“購買成功”頁面掃碼入群,即可與技術(shù)大咖們分享疑惑和經(jīng)驗(yàn)、收獲成長和認(rèn)同、領(lǐng)取優(yōu)惠和紅包等。

虛擬商品不可退

當(dāng)前內(nèi)容為數(shù)字版權(quán)作品,購買后不支持退換且無法轉(zhuǎn)移使用。

加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論
放大
實(shí)物圖
相關(guān)方案
  • 方案介紹
  • 相關(guān)文件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

原理圖Altium Designer
仿真版本:proteus7.8
程序編譯器:keil 4
設(shè)計(jì)編號:C0039

功能介紹:
1、單片機(jī)采用內(nèi)置AD的51系列單片機(jī),型號為STC89c52;
2、溫度采集采用DS18B20傳感器;
3、火災(zāi)煙霧檢測采用MQ-2傳感器,此傳感器輸出量也為模擬量,需接到單片機(jī)的AD端口上進(jìn)行采集;
4、防盜檢測采用HC-SR501熱釋電紅外感應(yīng)傳感器,通過配合板載設(shè)防開關(guān)進(jìn)行防盜的檢測;
5、報警部分分為板載蜂鳴器鳴笛報警和GSM短信報警功能,GSM采用SIM800模塊,當(dāng)溫度,煙霧濃度,防盜觸發(fā)時GSM短信模塊發(fā)送報警短信到指定的手機(jī)號碼上。
6、手機(jī)可以發(fā)送指令關(guān)閉繼電器或打開繼電器,給單片機(jī)打電話會回復(fù)短信單片機(jī)檢測的當(dāng)前溫度。

資料下載鏈接(可點(diǎn)擊)

仿真圖(提供源文件):

在這里插入圖片描述
在這里插入圖片描述

原理圖(提供源文件):

在這里插入圖片描述

PCB(源文件):

在這里插入圖片描述
在這里插入圖片描述

程序(提供源文件源碼):

#include <main.h>

void Waring_Processing(void)
{	
	//溫度超標(biāo)//煙霧超標(biāo)	
	if((Temperature >= Temp_H) ||( MQ_Value>= MQ_2))
	{		
		BEEP_Cnt = 55;
		if(SMS_Enable_Time == 0)
			{
				SMS_States_Register |= (1 << SMS_TXD_ENA);	
				SMS_Enable_Time = 30; //30秒內(nèi)只發(fā)一條短信
				SMS_Retry = 3;
				SMS_Type = 0;
			}			
	}	
}

void main(void)
{	
	alarm_1 = 0;	
	EEPROM_Init();
	LcmInit();
	DS18B20_Init();
	Time0_Init();
	UART0_Init();
	KEY_Init();
	EA = 1;	
	while(1)
	{
		Waring_Processing();
		KEY_Processing();
		UART0_Processing();
		SMS_Processing();
		DS18B20_Processing();
		ADC0832_Processing();
		IR_Processing();
		EEPROM_Processing();
	}
}

/*
               
            DS1820/DS18B20 數(shù)字溫度傳感器通用程序庫


  說明:該模塊化程序庫包含了數(shù)字溫度傳感器DS1820/DS18B20測溫所需的相關(guān)
        函數(shù)??梢宰鳛楦鞣N測溫程序的底層硬件驅(qū)動使用。
        要使用該庫函數(shù),需要將本文件(18x20.c)添加進(jìn)工程,并在需要調(diào)用
        測溫相關(guān)函數(shù)的文件開頭處包含"18x20.h"
        注意,本程序適用的晶振頻率范圍為8-14MHz(指令周期1us左右)。
        如果時鐘頻率差別較大,需要修改Delay10()函數(shù),使之大約10us左右,
        并修改Delay15()函數(shù),使之大約15us左右。
  
  
*/


//
//                                          VCC
//                   MCU=89x51/52           ---  長線時DQ腳要上拉
//               +---------------+           |
//               |               |           |     數(shù)字溫度傳感器
//               |               |       +---+------------------+
//               |               |       |                      |
//               |          P3.7 |<----->|   DS18B20 / DS1820   |
//               |               |   DQ  |                      |
//               |               |       +----------------------+
//               |               |           |    
//               |               |           |    
//               |               |           |    
//               +---------------+          ---
//                                          GND

#include <18X20.h>

sbit DQ=P3^7;         /* DS18B20數(shù)據(jù)引腳定義         */

bit TEMP_EA;
#define DISABLE_INT;  TEMP_EA=EA;  EA=0;  /*關(guān)閉中斷的宏定義*/
#define RESTORE_INT;  EA=TEMP_EA;         /*恢復(fù)中斷的宏定義*/


/****************************************************************************
* 名    稱:Delay10()
* 功    能:延遲10us
* 入口參數(shù):無
* 出口參數(shù):無
* 說    明: 指令周期1us時,延遲恰好10us,晶振改變延遲時間也會隨之改變
****************************************************************************/
void Delay10()
{ 
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();   // 6個NOP + 3周期LCALL(調(diào)用該函數(shù)) +1周期RET(返回)
  _nop_();   // = 10個指令周期
}

/****************************************************************************
* 名    稱:Delay15()
* 功    能:延遲15us
* 入口參數(shù):無
* 出口參數(shù):無
* 說    明: 指令周期1us時,延遲恰好15us,晶振改變延遲時間也會隨之改變
****************************************************************************/
void Delay15()
{ 
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();   // 11個NOP + 3周期LCALL(調(diào)用該函數(shù)) +1周期RET(返回)
  _nop_();   // = 15個指令周期
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
}

/****************************************************************************
* 名    稱:Delay30x()
* 功    能:延遲30us的倍數(shù)(會差幾個周期)
* 入口參數(shù):Time:30us的倍數(shù)
* 出口參數(shù):無
* 范    例: Delay30x(3); //延遲90us左右
****************************************************************************/
void Delay30x(unsigned char Time)
{  if(Time==0) return;  //Time=0次,不執(zhí)行
   for(;Time>0;Time--)  //循環(huán)Time次
    { 
      Delay15();        //每次延遲15us,加上循環(huán),大約28us。
    }
}

/****************************************************************************
* 名    稱:OW_Reset()
* 功    能:向1-Wire總線上發(fā)送一個復(fù)位指令。
* 入口參數(shù):無
* 出口參數(shù):1:表示復(fù)位操作成功
            0:表示復(fù)位操作失敗
****************************************************************************/
bit OW_Reset(void)//復(fù)位
{ unsigned char i;
  DISABLE_INT;  // 時序要求嚴(yán)格,不允許中斷 
  DQ = 0;       //pull DQ line low
  Delay30x(30); // leave it low for 480~960us  (700uS)
  DQ = 1;       // allow line to return high
  Delay30x(2);  // wait for presence 15~60uS    ( 56uS)  
  for(i=0;i<30;i++)  
     { 
       if (DQ==0) 
           {
            while(!DQ) {};// 復(fù)位成功,等待復(fù)位結(jié)束
            RESTORE_INT;
            return(1);   // 并返回1,表示有器件
           } 
       Delay15(); // 不成功,可能是1820反應(yīng)慢,重試30次
     } 
       RESTORE_INT;
       return(0);//  到達(dá)240uS等待最大值,放棄.返回0,表示無器件
}  



/****************************************************************************
* 名    稱:OW_ReadByte()
* 功    能:從 1-wire 總線上讀取一個字節(jié)。
* 入口參數(shù):無
* 出口參數(shù):讀回的1字節(jié)數(shù)據(jù)
****************************************************************************/
unsigned char OW_ReadByte(void)
{
  unsigned char i;
  unsigned char value = 0;
  for (i=8;i>0;i--)     // 讀取8比特循環(huán)8次,組成1字節(jié)
  {
    DISABLE_INT;        // 時序要求嚴(yán)格,不允許中斷
    value>>=1;
    DQ = 0;             // 將DQ腳拉低,表示寫比特時序開始
    _nop_();    
    _nop_();            // 保持低,1uS以上 (3uS)
    DQ = 1;             // 將DQ腳拉高
    Delay10();          // 延遲1uS~15uS (取10uS)
    if(DQ)  value|=0x80;// 讀取DQ的值
    Delay30x(5);        // wait for rest of timeslot 
    RESTORE_INT;        // 恢復(fù)中斷
  }
  return(value);
}


/****************************************************************************
* 名    稱:OW_WriteByte()
* 功    能:向 1-WIRE 總線上寫一個字節(jié)。
* 入口參數(shù):Val:寫入的1字節(jié)數(shù)據(jù)
* 出口參數(shù):無
****************************************************************************/
void OW_WriteByte(unsigned char Val)
{
  unsigned char i;
  for (i=8; i>0; i--)  // 寫入8比特循環(huán)8次,共計(jì)1字節(jié)
  {
    DISABLE_INT;       // 時序要求嚴(yán)格,不允許中斷
    DQ = 0;            // 將DQ腳拉低保持1uS以上 (3uS)
    DQ = Val&0x01;     // 先發(fā)低字節(jié)
    Delay30x(3);       // 保持?jǐn)?shù)據(jù) 60~120uS (取85uS)
    DQ = 1;            // DQ拉高
    Val=Val>>1;        // 取下一比特
    Delay15();         // 比特間延遲1us以上(取15us)
    RESTORE_INT;       // 恢復(fù)中斷
  }
}

/****************************************************************************
* 名    稱:DS1820_Conv()
* 功    能:向18B20發(fā)指令:開始溫度測量與轉(zhuǎn)換。
* 入口參數(shù):無
* 出口參數(shù):無
* 說    明: 該命令發(fā)出后,必須等待至少500-700ms才能測量完畢,之后才能讀取數(shù)據(jù)。
****************************************************************************/
void DS1820_Conv()
{
  OW_Reset();         // 復(fù)位18B20
  OW_WriteByte(0xCC); // Skip  ROM(不進(jìn)行序列號識別)
  OW_WriteByte(0x44); // 開始轉(zhuǎn)換
}

/****************************************************************************
* 名    稱:DS1820_GetFamily()
* 功    能:讀取18x20的家族代碼。
* 入口參數(shù):無
* 出口參數(shù):讀回的家族號。
* 說    明: 0x10表示DS1820,0x28表示DS18B20,更多系列請參照官方數(shù)據(jù)手冊
****************************************************************************/
unsigned char DS1820_GetFamily()
{ unsigned char FamilyID;
  OW_Reset();               // 復(fù)位18B20
  OW_WriteByte(0x33);       // 發(fā)出獲取家族代碼命令
   FamilyID=OW_ReadByte();  // 讀取家族號
   return(FamilyID);        // 返回
}
/****************************************************************************
* 名    稱:DS1820_GetTemp()
* 功    能:讀取18x20的溫度測量結(jié)果。注意要在DS1820_Conv()命令至少之后700ms以
            后調(diào)用,才能讀取準(zhǔn)確的溫度值。
* 入口參數(shù):無
* 出口參數(shù):溫度數(shù)值,保留1位小數(shù)。
            返回0x8001表示未檢測到器件
            返回0x8002表示無法識別的器件       
* 范    例: 返回123表示12.3度;-345表示-34.5度,依此類推
****************************************************************************/
int DS1820_GetTemp()
{
  unsigned char tempH,tempL,Family;
  if(OW_Reset()==0) return(0x8001);// 若復(fù)位不成功說明無器件,返回0x8001
  Family=DS1820_GetFamily();       // 讀取1820的家族代碼
  OW_Reset();                      // 復(fù)位,結(jié)束讀取家族代碼的操作
  OW_WriteByte(0xCC);              // Skip ROM(不進(jìn)行序列號識別)
  OW_WriteByte(0xBE);              // 發(fā)出讀取數(shù)據(jù)的指令
  Delay30x(5);                     // 略延遲
  tempL=OW_ReadByte();             // 讀取溫度轉(zhuǎn)換結(jié)果_低8位
  tempH=OW_ReadByte();             // 讀取溫度轉(zhuǎn)換結(jié)果_高8位
  if (Family==0x28)                // 如果是DS18B20系列
     {
       return ((tempH*256+tempL)*(long)625/1000);//計(jì)算溫度,保留1位小數(shù) 
     }
  else if(Family==0x10)            // 如果是DS1820系列(比18B20更老的型號)
     {
       return ((tempH*256+tempL)*5);//計(jì)算溫度,保留1位小數(shù)  
     }
  else return(0x8002);             //其它型號無法識別 返回0x8002  
}


void DS18B20_Init(void)
{
	DS1820_GetTemp();      //讀取上次測溫結(jié)果
	//		PutTemp(1,3,Temperature);
			//LED_DisplayDecimal(Temperature,1); //顯示測溫結(jié)果,保留1位小數(shù)
	DS1820_Conv();                     //發(fā)送下一次測溫開始命令
	
	DS1820_GetTemp();      //讀取上次測溫結(jié)果
	//		PutTemp(1,3,Temperature);
			//LED_DisplayDecimal(Temperature,1); //顯示測溫結(jié)果,保留1位小數(shù)
	DS1820_Conv();                     //發(fā)送下一次測溫開始命令
	
	DS1820_GetTemp();      //讀取上次測溫結(jié)果
	//		PutTemp(1,3,Temperature);
			//LED_DisplayDecimal(Temperature,1); //顯示測溫結(jié)果,保留1位小數(shù)
	DS1820_Conv();                     //發(fā)送下一次測溫開始命令
	
}


volatile int Temperature;

void DS18B20_Processing(void)
{

		if(Time0_2s_Flag)                      //2ms累加500次共計(jì)1秒
		{
			Time0_2s_Flag = 0;                        //以下代碼每隔2秒執(zhí)行一次 
			
			Temperature = DS1820_GetTemp();      //讀取上次測溫結(jié)果
			PutTemp(1,3,Temperature);
			//LED_DisplayDecimal(Temperature,1); //顯示測溫結(jié)果,保留1位小數(shù)
			DS1820_Conv();                     //發(fā)送下一次測溫開始命令
		}	

}


ADC0832驅(qū)動程序


#include <ADC0832.H>







unsigned char Get_AD_Result(bit CH)
{

	unsigned char i;
	unsigned char dat;
	ADC0832_CS=1;   //一個轉(zhuǎn)換周期開始
	ADC0832_CLK=0;  //為第一個脈沖作準(zhǔn)備
	ADC0832_CS=0;  //CS置0,片選有效
	ADC0832_DIO=1;    //DIO置1,規(guī)定的起始信號  
	ADC0832_CLK=1;   //第一個脈沖
	ADC0832_CLK=0;   //第一個脈沖的下降沿,此前DIO必須是高電平
	ADC0832_DIO=1;   //DIO置1, 通道選擇信號  
	ADC0832_CLK=1;   //第二個脈沖,第2、3個脈沖下沉之前,DI必須跟別輸入兩位數(shù)據(jù)用于選擇通道,這里選通道RH0 
	ADC0832_CLK=0;   //第二個脈沖下降沿 
	ADC0832_DIO=CH;   //DI置0,選擇通道0
	ADC0832_CLK=1;    //第三個脈沖
	ADC0832_CLK=0;    //第三個脈沖下降沿 
	ADC0832_DIO=1;    //第三個脈沖下沉之后,輸入端DIO失去作用,應(yīng)置1
	ADC0832_CLK=1;    //第四個脈沖
	
	for(i=0;i<8;i++)  //高位在前
	{
		ADC0832_CLK=1;         //第四個脈沖
		ADC0832_CLK=0; 
		dat<<=1;       //將下面儲存的低位數(shù)據(jù)向右移
		dat|=(unsigned char)ADC0832_DIO; 	 //將輸出數(shù)據(jù)DIO通過或運(yùn)算儲存在dat最低位 
	}	  		        
	ADC0832_CS=1;          //片選無效 
	return dat;	 //將讀書的數(shù)據(jù)返回     


}


volatile unsigned char MQ_Value;

void ADC0832_Processing(void)
{

	if(Time0_1s_Flag2)
	{
		Time0_1s_Flag2 = 0;
		
		MQ_Value = Get_AD_Result(0);
	
		PutNum(2,3,MQ_Value);
	}
}
















按鍵掃描函數(shù)


#include <KEY.H>


volatile unsigned char KEY_Value = 0;


void KEY_Init(void)
{
	
	P1  |= 0X20;
	P3  |= 0X24;
}


unsigned char KEY_Read(void)
{
	unsigned char a;
	
	a = (P1 & 0x20) + ((P3&0x24)>>1);

	return a;
}


void KEY_Scan(void)  //每20m調(diào)用一次
{
	 unsigned char KEY_Data;
	 static unsigned char KEY_Cont = 0;
	 static unsigned char KEY_Counter = 0;
	 static unsigned char KEY_States = 0;
	 static unsigned char KEY_Wait = 0;
	
	 KEY_Data =  KEY_Read();
	
	 KEY_Value = KEY_Data & (KEY_Data ^ KEY_Cont);
	 
	 KEY_Cont = KEY_Data;
	
		 
	 if(KEY_Cont && (KEY_Cont != 0x08))  //連續(xù)按下禁止SET連續(xù)觸發(fā)
	 {
		 if(KEY_Wait > 25) //500ms進(jìn)入連續(xù)觸發(fā)
		 {
			 if(KEY_Counter >= 2)  //每秒觸發(fā) 25 = 1000/20/2
			 {
				 KEY_Counter = 0;
				 KEY_Value = KEY_Cont;
			 }
			 else
			 {
				 KEY_Counter++;
			 }
		 }
		 else
		 {
			 KEY_Wait++;
		 }
	 }
	 else
	 {
		 KEY_States = 0;
		 KEY_Wait = 0;
	 }
	 
	 if(KEY_Value)
	 {
		 
		 switch(KEY_Value)
		 {
				case 0x00: KEY_Value = KEY_NOP;  break;
				
				case 0x20: KEY_Value = KEY_SET;  break;
				
				case 0x10: KEY_Value = KEY_UP;   break;
						
				case 0x02: KEY_Value = KEY_DOW;  break;
			 
				default: KEY_Value = KEY_NOP;    break;
		 }
	 }
}


volatile unsigned int Temp_H = 150;
volatile unsigned char MQ_2 = 80;


void KEY_Processing(void)
{

	
	//按鍵掃描
	if(Time0_20ms_Flag)
	{
		Time0_20ms_Flag = 0;
		KEY_Scan();	
	}
		
	
	if(KEY_Value == KEY_SET)
	{
		KEY_Value = KEY_NOP;
		
	}
	else if(KEY_Value == KEY_UP)
	{
		KEY_Value = KEY_NOP;
		

		PutNum(2,5,2);
		
		LcmClearTXT();
		
		PutStr(0,0,"設(shè)置溫度報警");
		PutStr(1,0,"溫度:");	
		while(1)
		{
			
			if(Time0_100ms_Flag)
			{
				Time0_100ms_Flag = 0;
				PutTemp(1,3,Temp_H);
			}
				//按鍵掃描
			if(Time0_20ms_Flag)
			{
				Time0_20ms_Flag = 0;
				KEY_Scan();	
			}
			
			if(KEY_Value == KEY_SET)
			{
				KEY_Value = KEY_NOP;
				
				if(Temp_H <990)
				Temp_H++;
			}
			
			else if(KEY_Value == KEY_UP)
			{
				KEY_Value = KEY_NOP;
				break;
			  
		  }
			else if(KEY_Value == KEY_DOW)
			{
				KEY_Value = KEY_NOP;
				
				if(Temp_H > 1)
				Temp_H--;
			}
	 }
	 
		LcmClearTXT();
		
		PutStr(0,0,"設(shè)置煙霧報警");
		PutStr(2,0,"煙霧:");
		while(1)
		{

			if(Time0_100ms_Flag)
			{
				Time0_100ms_Flag = 0;
				PutNum(2,3,MQ_2);
			}
				//按鍵掃描
			if(Time0_20ms_Flag)
			{
				Time0_20ms_Flag = 0;
				KEY_Scan();	
			}
			
			if(KEY_Value == KEY_SET)
			{
				KEY_Value = KEY_NOP;
				
				if(MQ_2 <250)
				MQ_2++;
			}
			
			else if(KEY_Value == KEY_UP)
			{
				KEY_Value = KEY_NOP;
				break;
			  
		  }
			else if(KEY_Value == KEY_DOW)
			{
				KEY_Value = KEY_NOP;
				
				if(MQ_2 > 1)
				MQ_2--;
			}			
			
		}
		LcmInit();
		EEPROM_Save_Flag = 1;
	}
	else if(KEY_Value == KEY_DOW)
	{
		KEY_Value = KEY_NOP;
		
	}

}

資料清單(提供資料清單所有文件):

在這里插入圖片描述

  • 設(shè)計(jì)資料獲取聯(lián)系方式.doc

相關(guān)推薦

電子產(chǎn)業(yè)圖譜