欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
單片機智能家居安防系統設計 GSM通訊程序
[打印本頁]
作者:
dnsy
時間:
2019-12-8 20:42
標題:
單片機智能家居安防系統設計 GSM通訊程序
1、可檢測火焰光源;
2、可檢測非法入室的人員;
3、可檢測可燃氣體;
4、發生以上事故可將報警信息遠程傳輸到戶主手機上
51hei.png
(73.15 KB, 下載次數: 56)
下載附件
2019-12-9 00:59 上傳
單片機源程序如下:
#include "config.h"
#include "string.h"
#include "delay.h"
#include "uart.h"
#define Buf1_Max 200 //串口2緩存長度
/************* 本地常量聲明 **************/
sbit RUNING_LED = P2^7; //運行指示燈
sbit HW = P1^6; //運行指示燈
static unsigned char *content="8D706C344E86002C5FEB6551706B0021";//發送短信內容 走水了,快救火!
/************* 本地變量聲明 **************/
xdata u8 Uart1_Buf[Buf1_Max];
u8 Times=0,First_Int = 0,shijian=0;
bdata u8 Flag;//定時器標志位
sbit Timer0_start =Flag^0; //定時器0延時啟動計數器
/************* 本地函數聲明 **************/
void GPIO_config(void); //端口初始化配置
void Timer0Init(void); //定時器0初始化
void CLR_Buf1(void); //清除串口2接收緩存
u8 Find(u8 *a); //查找字符串
void Second_AT_Command(u8 *b,u8 *a,u8 wait_time); //發送AT指令函數
void Set_Pdu_Mode(void);//設置短信模式PDU
void Wait_CREG(void); //查詢等待模塊注冊成功
void Send_Pdu_Sms(void);//發送一條中文短信
/************* 外部函數和變量聲明*****************/
u8 yushe_wendu=50; //溫度預設值
u16 wendu; //溫度值全局變量
u8 yushe_yanwu=45; //煙霧預設值
u8 yanwu; //用于讀取ADC數據
//運行模式
u8 Mode=0; //=1是設置溫度閥值 =2是設置煙霧閥值 =0是正常監控模式
void Init_Timer0(void);
bit ReadTempFlag;//定義讀時間標志
//管腳聲明
//sbit Led_Reg =P2^7; //紅燈
sbit Buzzer =P3^3; //蜂鳴器
sbit DQ = P1^0; //ds18b20的數據引腳
#define SMG_NUM 4
u8 code DisplayNum[16]={
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e //F
};
//對應關系取字: dp g f e d c b a
//例如 U 1 1 0 0 0 0 0 1
u8 code DisplayOther[]={
0xff, //0 空
0x7f, //1 "."
0xbf, //2 "-"
0xa7, //3 c
0xC1, //4 U
~0x6e //5 y
};
/********************************************************************
* 名稱 : delay_1ms()
* 功能 : 延時1ms函數
* 輸入 : q
* 輸出 : 無
***********************************************************************/
void delay1_ms(u16 q)
{
u16 i,j;
for(i=0;i<q;i++)
for(j=0;j<110;j++);
}
//數碼管位選定義
sbit smg_we1 = P2^0; //
sbit smg_we2 = P2^1; //
sbit smg_we3 = P2^2; //
sbit smg_we4 = P2^3; //
/***********************數碼位選函數*****************************/
void smg_we_switch(u8 i)
{
smg_we1 = 1;
smg_we2 = 1;
smg_we3 = 1;
smg_we4 = 1;
switch(i)
{
case 0: smg_we1 = 0; break;
case 1: smg_we2 = 0; break;
case 2: smg_we3 = 0; break;
case 3: smg_we4 = 0; break;
}
}
/********************************************************************
* 名稱 : u8 ChangeFor(u8 dat)
* 功能 : 交換一個字節位的位置,用于數碼管顯示
* 輸入 : 需要改變的數
* 輸出 : 改變后的數
***********************************************************************/
#define LED_a 0 //數碼管段選的a段接在段選IO口的第0位
#define LED_b 2
#define LED_c 6
#define LED_d 4
#define LED_e 3
#define LED_f 1
#define LED_g 7
#define LED_dp 5
u8 ChangeFor(u8 dat)
{
u8 temp=0;
if(dat&0x01) //判斷數據的第一位是否為1
temp|=0x01<<LED_a;//如果為1,放到控制數碼管a段的位置
if(dat&0x02)
temp|=0x01<<LED_b;
if(dat&0x04)
temp|=0x01<<LED_c;
if(dat&0x08)
temp|=0x01<<LED_d;
if(dat&0x10)
temp|=0x01<<LED_e;
if(dat&0x20)
temp|=0x01<<LED_f;
if(dat&0x40)
temp|=0x01<<LED_g;
if(dat&0x80)
temp|=0x01<<LED_dp;
return temp;
}
u8 dis_smg[SMG_NUM]; //顯示緩存數組
/********************************************************************
* 名稱 : display()
* 功能 : 數碼管顯示
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void DisplayScan()
{
static u8 i;
P0 = 0xff; //消隱
smg_we_switch(i); //位選
P0 = ChangeFor(dis_smg[i]); //段選
i++;
if(i>=SMG_NUM)
i=0;
}
/*****延時子程序:該延時主要用于ds18b20延時*****/
void Delay_DS18B20(int num)
{
while(num--) ;
}
/*****初始化DS18B20*****/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ復位
Delay_DS18B20(8); //稍做延時
DQ = 0; //單片機將DQ拉低
Delay_DS18B20(80); //精確延時,大于480us
DQ = 1; //拉高總線
Delay_DS18B20(14);
x = DQ; //稍做延時后,如果x=0則初始化成功,x=1則初始化失敗
Delay_DS18B20(20);
}
/*****讀一個字節*****/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
ET0=0; //定時器中斷關閉
DQ = 0; // 給脈沖信號
dat>>=1;
DQ = 1; // 給脈沖信號
if(DQ)
dat|=0x80;
Delay_DS18B20(4);
ET0=1; //定時器中斷打開
}
return(dat);
}
/*****寫一個字節*****/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
ET0=0; //定時器中斷關閉
DQ = 0;
DQ = dat&0x01;
Delay_DS18B20(5);
DQ = 1;
dat>>=1;
ET0=1; //定時器中斷打開
}
}
u8 tempflag=0; //負號顯示
/*****讀取溫度*****/
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
u8 tt=0;
u8 ttt=0;
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0x44); //啟動溫度轉換
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0xBE); //讀取溫度寄存器
a=ReadOneChar(); //讀低8位
b=ReadOneChar(); //讀高8位
t=b;
t<<=8;
t=t|a; //合并高低位為一個字節
tt=(u8)(t>>4); //得到整數位
ttt=(u8)((t%16)*0.0625*10); //得到小數位;乘以10代表保留一位小數;
if(tt&0x80)
{
tempflag=1; //負號顯示
tt=~tt+1; //實際溫度值為讀取值的補碼
}
else
tempflag=0; //正號顯示
t= tt*10+ttt; //放大10倍
return(t);
}
/*****校準溫度*****/
u16 check_wendu(void)
{
u16 c;
c=ReadTemperature(); //獲取溫度值并減去DS18B20的溫漂誤差
return c;
}
//按鍵
sbit Key1=P1^6; //設置鍵
sbit Key2=P1^7; //加按鍵
sbit Key3=P3^2; //減按鍵
#define KEY_SET 1 //設置
#define KEY_ADD 2 //加
#define KEY_MINUS 3 //減
//========================================================================
// 函數: u8 Key_Scan()
// 應用: temp=u8 Key_Scan();
// 描述: 按鍵掃描并返回按下的鍵值
// 參數: NONE
// 返回: 按下的鍵值
// 版本: VER1.0
// 日期: 2015-05-29
// 備注: 該函數帶松手檢測,按下鍵返回一次鍵值后返回0,直至第二次按鍵按下
//========================================================================
u8 Key_Scan()
{
static u8 key_up=1;//按鍵按松開標志
if(key_up&&(Key1==0||Key2==0||Key3==0))
{
delay1_ms(10);//去抖動
key_up=0;
if(Key1==0) return 1;
else if(Key2==0)return 2;
else if(Key3==0)return 3;
}
else if(Key1==1&&Key2==1&&Key3==1)
key_up=1;
return 0;// 無按鍵按下
}
/***********************************************************************************************************
ADC0832相關函數
***********************************************************************************************************/
sbit AD0832_CS = P1^5 ; //片選信號
sbit AD0832_CLK = P1^2; //時鐘接口
sbit AD0832_DI = P1^3; //數據接口 /*因為單片機的管腳是雙向的,且ADC0832的數據輸入輸出不同時進行,為節省單片機引腳,簡化電路所以輸入輸出連接在同一個引腳上*/
u8 GetAD0832(bit Channel)
{
u8 i=0 , Data1 =0 , Data2 = 0 ;
AD0832_CLK = 0 ; //時鐘置低平//時鐘12Mhz, 整個轉換時間為224us
//使用芯片準備(參考PDF時序圖)
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; //數據左移位,補0
if(AD0832_DI ==1)
{
Data1 = Data1 | 0x01;
} //如果數據為“1”,移入1,
} //如果數據為“0”,移入0,
for(i=0;i<8;i++) //從低位移入數據
{
Data2 = Data2>>1; //數據左移位,補0
if(AD0832_DI ==1)
{
Data2 = Data2 | 0x80;
} //如果數據為“1”,移入1如果數據為“0”,移入0,
AD0832_CLK = 1;
AD0832_CLK = 0; //時鐘下降沿,AD0832輸出數據,高位(MSB)先
}
//數據線置高,釋放總線,完成一次轉換
AD0832_CLK = 1 ;
AD0832_DI = 1;
AD0832_CS = 1;
if(Data1==Data2) //輸出
{
return Data2;
}
return 0;
}
/*******************************************************************************
* 函數名 : Set_Text_Mode
* 描述 : 設置短信為TEXT文本模式
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Set_Text_Mode(void)
{
Second_AT_Command("ATE0","OK",3); //取消回顯
Second_AT_Command("AT+CNMI=3,2,0,0,0","OK",3); //新短信直接輸出
Second_AT_Command("AT+CMGF=1","OK",3); //TEXT模式
Second_AT_Command("AT+CPMS=\"SM\",\"SM\",\"SM\"","OK",3); //所有操作都在SIM卡中進行
}
/*******************************************************************************
* 函數名 : main
* 描述 : 主函數
* 輸入 :
* 輸出 :
* 返回 :
* 注意 : 串口波特率是9600,GPRS模塊默認波特率是115200,需要自己通過串口助手修改
為9600方可使用。
*******************************************************************************/
void main(void)
{
u8 key;
u8 bj=0;
u16 i=0;
Timer0Init(); //初始化定時器0
dis_smg[0] = DisplayOther[2] ;
dis_smg[1] = DisplayOther[2] ;
dis_smg[2] = DisplayOther[2] ;
dis_smg[3] = DisplayOther[2] ;
GPIO_config();
EA=1; //開總中斷
Uart1Init(); //初始化串口9600
Wait_CREG(); //查詢等待模塊注冊成功
Set_Text_Mode();//設置短信為TEXT模式
Buzzer=0; //打開蜂鳴器報警
wendu=check_wendu(); //初始化時調用溫度讀取函數 防止開機85°C
delay1_ms(1000);
wendu=check_wendu(); //初始化時調用溫度讀取函數 防止開機85°C
Buzzer=1; //打開蜂鳴器報警
while (1) //主循環
{
key=Key_Scan(); //按鍵掃描
i++;
if(i>=2000)
{
i=0;
wendu=check_wendu(); //讀取溫度值
yanwu=GetAD0832(0)*100/255; //讀取煙霧值
}
if(key==KEY_SET)
{
Mode++;
}
switch(Mode) //判斷模式的值
{
case 0: //監控模式
dis_smg[0] = DisplayNum[wendu/100%10] ;
dis_smg[1] = DisplayNum[wendu/10%10];
dis_smg[2] = DisplayNum[yanwu/10%10] ;
dis_smg[3] = DisplayNum[yanwu%10] ;
if((yanwu<yushe_yanwu)&&(wendu<(yushe_wendu*10))) //當煙霧小于預設值并且溫度也小于預設值時 (&&:邏輯與,左右兩邊的表達式都成立(都為真,也就是1)時,該if語句才成立)
{
Buzzer=1; //打開蜂鳴器報警
bj=0;
}
else //溫度值小于預設值時
{
Buzzer=0; //停止報警
if(bj==0)
{
bj=1;
Set_Pdu_Mode();//設置短信為PDU模式
Send_Pdu_Sms();//發送一條短消息
}
}
break;
case 1://預設溫度模式
{
dis_smg[0] = DisplayNum[0xc];
dis_smg[1] = DisplayOther[2] ;
dis_smg[2] = DisplayNum[yushe_wendu/10%10];
dis_smg[3] = DisplayNum[yushe_wendu%10] ;
if(key==KEY_ADD) //加鍵按下
{
yushe_wendu++; //預設溫度值(閥值)加1
if(yushe_wendu>=99) //當閥值加到大于等于99時
yushe_wendu=99; //閥值固定為99
}
if(key==KEY_MINUS) //減鍵按下
{
if(yushe_wendu<=1) //當溫度上限值減小到1時
yushe_wendu=1; //固定為1
yushe_wendu--; //預設溫度值減一,最小為0
}
break; //執行后跳出switch
}
case 2://預設煙霧模式
{
dis_smg[0] = DisplayOther[5];
dis_smg[1] = DisplayOther[2] ;
dis_smg[2] = DisplayNum[yushe_yanwu/10%10];
dis_smg[3] = DisplayNum[yushe_yanwu%10] ;
if(key==KEY_ADD) //加鍵按下
{
yushe_yanwu++; //預設溫度值(閥值)加1
if(yushe_yanwu>=99) //當閥值加到大于等于99時
yushe_yanwu=99; //閥值固定為99
}
if(key==KEY_MINUS) //減鍵按下
{
if(yushe_yanwu<=1) //當溫度上限值減小到1時
yushe_yanwu=1; //固定為1
yushe_yanwu--; //預設溫度值減一,最小為0
}
break; //執行后跳出switch
}
default :
{
Mode=0; //恢復正常模式
break;
}
}
}
}
/*******************************************************************************
* 函數名 : Uart1
* 描述 : 串口1中斷服務入口函數
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Uart1() interrupt 4
{
if (RI)
{
RI = 0; //清除RI位
Uart1_Buf[First_Int] = SBUF; //將接收到的字符串存到緩存中
First_Int++; //緩存指針向后移動
if(First_Int > Buf1_Max) //如果緩存滿,將緩存指針指向緩存的首地址
{
First_Int = 0;
}
}
if (TI)
{
TI = 0; //清除TI位
}
}
/*******************************************************************************
* 函數名 : Timer0_ISR
* 描述 : 定時器0中斷服務入口函數,20ms中斷一次
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Timer0_ISR() interrupt 1
{
static u16 Time_count=0;
static u8 i=0;
TL0 = 0xCD; //設置定時初值
TH0 = 0xF8; //設置定時初值
TR0=0;//關定時器
DisplayScan();// 調用數碼管掃描
i++;
if(i>=10)
{
i=0;
Time_count++;
if(Time_count>=50)
{
Time_count = 0;
RUNING_LED =~RUNING_LED;
}
if(count_20ms) //20ms延時計數器
count_20ms--;
if(Timer0_start)
Times++;
if(Times > (50*shijian))
{
Timer0_start = 0;
Times = 0;
}
}
TR0=1;//開定時器
}
/*******************************************************************************
* 函數名 : GPIO_config
* 描述 : IO口配置函數
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void GPIO_config(void)
{
RUNING_LED=0;
}
/*******************************************************************************
* 函數名 : Timer0Init
* 描述 : 定時器0初始化,20ms定時
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Timer0Init(void) //20毫秒@11.0592MHz
{
AUXR &= 0x7F; //定時器時鐘12T模式
TMOD &= 0xF0; //
TMOD |= 0x01; //設置定時器模式,16位定時器
TL0 = 0xCD; //設置定時初值
TH0 = 0xF8; //設置定時初值
TF0 = 0; //清TF0標志
TR0 = 1; //定時器0開始計時
ET0 = 1; //使能定時器0中斷
}
/*******************************************************************************
* 函數名 : CLR_Buf1
* 描述 : 清除串口2緩存數據
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void CLR_Buf1(void)
{
u16 k;
for(k=0;k<Buf1_Max;k++) //將緩存內容清零
{
Uart1_Buf[k] = 0x00;
}
First_Int = 0; //接收字符串的起始存儲位置
}
/*******************************************************************************
* 函數名 : Find
* 描述 : 判斷緩存中是否含有指定的字符串
* 輸入 :
* 輸出 :
* 返回 : unsigned char:1 找到指定字符,0 未找到指定字符
* 注意 :
*******************************************************************************/
u8 Find(u8 *a)
{
if(strstr(Uart1_Buf,a)!=NULL)
return 1;
else
return 0;
}
/*******************************************************************************
* 函數名 : Second_AT_Command
* 描述 : 發送AT指令函數
* 輸入 : 發送數據的指針、發送等待時間(單位:S)
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Second_AT_Command(u8 *b,u8 *a,u8 wait_time)
{
u8 i;
u8 *c;
c = b; //保存字符串地址到c
CLR_Buf1();
i = 0;
while(i == 0)
{
if(!Find(a)) //查找需要應答的字符
{
if(Timer0_start == 0)//超時重新發送命令
{
b = c; //將字符串地址給b
for (b; *b!='\0';b++)
{
UART1_SendData(*b);
}
UART1_SendLR();
Times = 0;
shijian = wait_time;
Timer0_start = 1; //開始計時
}
}
else
{
i = 1;
Timer0_start = 0;
}
}
CLR_Buf1();
}
/*******************************************************************************
* 函數名 : Set_Pdu_Mode
* 描述 : 設置短信為TEXT文本模式
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Set_Pdu_Mode(void)
{
Second_AT_Command("ATE0","OK",3); //取消回顯
Second_AT_Command("AT+CMGF=1","OK",3); //設置為文本模式
Second_AT_Command("AT+CSMP=17,167,2,25","OK",3); //設置文本模式參數
}
/*******************************************************************************
* 函數名 : Send_Pdu_Sms
* 描述 : 發送PDU文本短信
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Send_Pdu_Sms(void)
{
Second_AT_Command("AT+CSCS=\"UCS2\"","OK",3); //設置為 UCS2 編碼字符集
Second_AT_Command("AT+CMGS=\"00310033003200340033003100360031003500360035\"",">",3);
UART1_SendString(content); //發送短信內容
UART1_SendData(0X1A); //發送結束符
}
/*******************************************************************************
* 函數名 : Wait_CREG
* 描述 : 等待模塊注冊成功
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Wait_CREG(void)
{
u8 i;
u8 k;
i = 0;
CLR_Buf1();
while(i == 0)
{
CLR_Buf1();
UART1_SendString("AT+CREG");//查詢模塊網絡注冊狀態
UART1_SendLR();
delay_ms(250);
for(k=0;k<Buf1_Max;k++)
{
if(Uart1_Buf[k] == ':')
{
if((Uart1_Buf[k+4] == '2')||(Uart1_Buf[k+4] == '5')) //表明網絡注冊成功
{
i = 1;
break;
}
}
}
}
}
復制代碼
原理圖,代碼:
定做資料.zip
(432.64 KB, 下載次數: 190)
2019-12-8 20:42 上傳
點擊文件名下載附件
智能家居安防系統設計
下載積分: 黑幣 -5
仿真: 無
作者:
dnsy
時間:
2019-12-8 20:44
電路圖,程序
作者:
fengbujueQAQ
時間:
2024-2-21 16:12
dnsy 發表于 2019-12-8 20:44
電路圖,程序
打開原理圖的軟件可以仿真嗎
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1