/********************************************** 設(shè)計者:胥學辰 時間:2011-11-1——2011-11-6 功能:18B20采集溫度,dht11采集濕度,光敏電阻采集光照等, 通過GSM接受指令傳輸參數(shù),控制外部器件改變環(huán)境參數(shù)。 完整代碼下載:http://www.torrancerestoration.com/f/gpsdd.rar ***********************************************/ #include<reg52.h> #include<intrins.h> #include<string.h> #include<stdio.h> #define uchar unsigned char #define uint unsigned int sbit DQ_wen=P2^0; sbit DQ_shi=P2^1; uchar i=0,j=0,flag,tm,temp,wet,dat; char num[]="15282983798"; //定義要撥打的電話號碼 char code Huifu_S[]="Fa Song Success!"; //定義成功發(fā)送要回復的內(nèi)容 char code Huifu_F[]="Fa Song Failure!"; //定義失敗發(fā)送要回復的內(nèi)容 char Huifu_wsg[]="temp:00.00C wet:23%R"; //定義參數(shù)回復數(shù)組 char xdata Huancun[200]; //定義返回值存儲數(shù)組 char code Ok[]="OK"; //返回OK值標志 char code CMTI[]="+CMTI"; //接收短信標志 char code open_1[]="open1"; //短信控制1標志 char code open_2[]="open2"; //短信控制2標志 char code open_3[]="open3"; //短信控制3標志 char code open_4[]="open4"; //短信控制4標志 void delay_key(uchar z); //按鍵延時函數(shù) void delay_GSM(uint y); //GSM模塊延時函數(shù) void delay_18b20(uchar i); //18b20延時函數(shù) void delay_dht11_C(uint j); //dht11長延時函數(shù) void delay_dht11_D(uchar i); //dht11短延時函數(shù) void chuankou_init(); //串口初始化函數(shù) void clear_huancun(); //清除緩存函數(shù) void send_ASCII(uchar *b); //發(fā)送ASCII代碼函數(shù) void send_16_Hex(uchar c); //發(fā)送16進制代碼函數(shù) bit panduan(uchar *a,uchar *b); //判斷是否返回OK與短信成功代碼 void GSM_Text_Message(uchar*num,uchar*Huifu); //Text模式短信發(fā)送函數(shù) void GSM_Call(uchar *num); //撥打電話函數(shù) void Tiqu_num(); //提取來電號碼函數(shù) void init_18b20(); //18b20初始復位函數(shù) void write_18b20_dat(uchar dat); //18b20寫入字節(jié)函數(shù) uchar read_18b20_dat(); //18b20讀出字節(jié)函數(shù) uchar read_18b20_temp_zs(); //18b20讀取溫度整數(shù)函數(shù) uchar read_18b20_temp_xs(); //18b20讀取溫度小數(shù)函數(shù) void dht11_init(void); //dht11初始化函數(shù) uchar read_dht11(void); //dht11讀取濕度函數(shù) void chuli_wen_wet_light(); //18b20_dht11_light處理函數(shù) void main() //主函數(shù) { chuankou_init(); //串口初始化 clear_huancun(); //清除緩存 delay_GSM(1000); //延時 while(!panduan(Huancun,Ok)) //判斷返回值 { send_ASCII("AT"); //發(fā)送聯(lián)機命令 send_16_Hex(0x0d); //發(fā)送回車符 send_16_Hex(0x0a); //發(fā)送換行符 P0=0x01; //步驟指示燈1 delay_GSM(600); //延時 } clear_huancun(); //清除緩存 P0=0x02; //步驟指示燈2 delay_GSM(600); //延時 send_ASCII("AT+CNMI=2,1"); //設(shè)置當有新短信到來時提示 send_16_Hex(0x0d); //發(fā)送回車符 send_16_Hex(0x0a); //發(fā)送換行符 delay_GSM(600); //延時 while(!panduan(Huancun,Ok)); //等待設(shè)置成功 clear_huancun(); //清除緩存內(nèi)容 P0=0x03; //步驟指示燈3 delay_GSM(600); //延時 send_ASCII("AT+CMGF=1"); //文本(TEXT)模式 send_16_Hex(0x0d); //發(fā)送回車符 send_16_Hex(0x0a); //發(fā)送換行符 delay_GSM(600); //延時 while(!panduan(Huancun,Ok)); //等待設(shè)置成功 clear_huancun(); //清除緩存內(nèi)容 P0=0x04; //步驟指示燈4 delay_GSM(600); //延時 send_ASCII("AT+CMGD=1"); //刪除第一條信息 send_16_Hex(0x0d); //發(fā)送回車符 send_16_Hex(0x0a); //發(fā)送換行符 delay_GSM(600); //延時 while(!panduan(Huancun,Ok)); //等待設(shè)置成功 clear_huancun(); //清除緩存內(nèi)容 while(1) //與GSM模塊聯(lián)機成功后的大循環(huán) { P0=0x05; //步驟指示燈5 chuli_wen_wet_light(); //實時采集處理溫度 if(panduan(Huancun,CMTI)) //若緩存字符串中含有"+CMTI"就表示有新的短信 { P0=0x06; //步驟指示燈6 clear_huancun(); //清除緩存內(nèi)容 delay_GSM(600); //延時 send_ASCII("AT+CMGR=1"); //發(fā)送讀取信息指令 send_16_Hex(0x0d); //發(fā)送回車符 send_16_Hex(0x0a); //發(fā)送換行符 delay_GSM(600); //延時 Tiqu_num(); //提取來電號碼 if(panduan(Huancun,open_1)) //如果信息內(nèi)容是"open1" { P0=0x10; //指示燈 GSM_Text_Message(num,Huifu_wsg); //發(fā)送環(huán)境參數(shù)信息 GSM_Text_Message(num,Huifu_S); //發(fā)送成功短信回復 } else if(panduan(Huancun,open_2)) //如果信息內(nèi)容是"open2" { P0=0x20; //指示燈 GSM_Text_Message(num,Huifu_S); //發(fā)送成功短信回復 } else if(panduan(Huancun,open_3)) //如果信息內(nèi)容是"open3" { P0=0x40; //指示燈 GSM_Text_Message(num,Huifu_S); //發(fā)送成功短信回復 } else if(panduan(Huancun,open_4)) //如果信息內(nèi)容是"open4" { P0=0x80; //指示燈 GSM_Text_Message(num,Huifu_S); //發(fā)送成功短信回復 } else GSM_Text_Message(num,Huifu_F); //發(fā)送失敗短信回復 clear_huancun(); //清除緩存內(nèi)容 delay_GSM(600); //延時 send_ASCII("AT+CMGD=1"); //刪除讀取后的信息 send_16_Hex(0x0d); //發(fā)送回車符 send_16_Hex(0x0a); //發(fā)送換行符 delay_GSM(600); //延時 while(!panduan(Huancun,Ok)); //等待設(shè)置成功 clear_huancun(); //清除緩存內(nèi)容 } } } /**************************** 各環(huán)節(jié)延時函數(shù) *****************************/ void delay_key(uchar x) //按鍵控制延時函數(shù) { uchar y; for(;x>0;x--) for(y=110;y>0;y--); } void delay_GSM(uint y) //GSM模塊延時函數(shù) { uint x; for(;y>0;y--) { x=1500; while(x--); } } void delay_18b20(uchar i) //18b20延時函數(shù) { while(i--); } void delay_dht11_C(uint j) //dht11長延時函數(shù) { uchar i; for(;j>0;j--) for(i=0;i<27;i++); } void delay_dht11_D(uchar i) //dht11短延時函數(shù) { for(;i>0;i--) _nop_(); } void chuankou_init() //串口初始化函數(shù) { SCON=0x50; //串口:方式1,允許發(fā)送和接收 TMOD=0x20; //定時器1:模式2,8位自動重裝模式,用于產(chǎn)生波特率 TH1=0xFD; //11.0592MHZ晶振,波特率為9600 TL1=0xFD; TR1=1; //開啟定時器1 ES=1; //開啟串口中斷 EA=1; //開啟全局中斷 } /**************************** GSM部分函數(shù) *****************************/ void clear_huancun() //清除緩存內(nèi)容函數(shù) { uchar k; for(k=0;k<200;k++) { Huancun[k]=0; //將緩存內(nèi)容清零 } i=0; //接收字符串的起始存儲位置 } void send_ASCII(uchar *b) //發(fā)送字符串函數(shù) { ES=0; //關(guān)串口中斷 for(b;*b!='\0';b++) { SBUF=*b; while(TI!=1); //等待發(fā)送完成 TI=0; //清除發(fā)送中斷標志位 } ES=1; //開串口中斷 } void send_16_Hex(uchar c) //發(fā)送16進制函數(shù) { ES=0; //關(guān)串口中斷 SBUF=c; while(TI!=1); //等待發(fā)送完成 TI=0; //清除發(fā)送中斷標志位 ES=1; //開串口中斷 } bit panduan(uchar *a,uchar *b) //判斷是否成功返回值函數(shù) { if(strstr(a,b)!=NULL) //如果a包含了b,則1;否則0 return 1; else return 0; } void Tiqu_num() //提取來電號碼函數(shù)函數(shù) { uchar i; for(i=0;i<11;i++) { num[i]=Huancun[i+36]; } } void GSM_Text_Message(uchar *num,uchar *Huifu) //Text模式短信發(fā)送 { send_ASCII("AT"); //發(fā)送聯(lián)機命令 send_16_Hex(0x0d); //發(fā)送回車符 send_16_Hex(0x0a); //發(fā)送換行符 delay_GSM(200); send_ASCII("AT+CMGF=1"); //發(fā)送TXET命令 send_16_Hex(0x0d); //發(fā)送回車符 send_16_Hex(0x0a); //發(fā)送換行符 delay_GSM(200); send_ASCII("AT+CSCS=GSM"); send_16_Hex(0x0d); //發(fā)送回車符 send_16_Hex(0x0a); //發(fā)送換行符 delay_GSM(200); send_ASCII("AT+CSMP=17,167,0,0"); send_16_Hex(0x0d); //發(fā)送回車符 send_16_Hex(0x0a); //發(fā)送換行符 delay_GSM(200); send_ASCII("AT+CMGS="); //接收短信手機號 send_ASCII(num); send_16_Hex(0x0d); //發(fā)送回車符 send_16_Hex(0x0a); //發(fā)送換行符 delay_GSM(200); send_ASCII(Huifu); //發(fā)送發(fā)送成功命令 send_ASCII("\x1a"); //16進制結(jié)束標志 delay_GSM(200); } void GSM_Call(uchar *num) //撥打電話函數(shù) { send_ASCII("ATD"); send_ASCII(num); send_ASCII("F;"); send_16_Hex(0x0d); //發(fā)送回車符 send_16_Hex(0x0a); delay_GSM(200); } /**************************** 18b20函數(shù) *****************************/ void init_18b20() { uchar a; DQ_wen=1; //DQ復位 delay_18b20(8); //稍做延時 DQ_wen=0; //單片機將DQ拉低 delay_18b20(80); //精確延時大于480us DQ_wen=1; //拉高總線 delay_18b20(14); //延時 a=DQ_wen; //稍做延時后 如果a=0則初始化成功 a=1則初始化失敗 delay_18b20(100); } void write_18b20_dat(uchar dat) //18b20寫入字符函數(shù) { uchar i; for(i=0;i<8;i++) { DQ_wen=0; DQ_wen=dat&0x01; delay_18b20(5); DQ_wen=1; dat>>=1; } } uchar read_18b20_dat() //18b20讀出字符函數(shù) { uchar i,dat=0; DQ_wen=1; for(i=0;i<8;i++) { DQ_wen=0; _nop_(); _nop_(); dat>>=1; DQ_wen=1; _nop_(); _nop_(); if(DQ_wen) dat|=0x80; delay_18b20(30); DQ_wen=1; } return dat; } uchar read_18b20_temp_zs() //18b20溫度整數(shù)讀取函數(shù) { uchar a,b,c; init_18b20(); write_18b20_dat(0xcc); write_18b20_dat(0x44); init_18b20(); write_18b20_dat(0xcc); write_18b20_dat(0xbe); a=read_18b20_dat(); b=read_18b20_dat(); c=a&0x0f; b<<=4; b+=(a&0xf0)>>4; return b; } uchar read_18b20_temp_xs() //18b20溫度小數(shù)讀取函數(shù) { uchar a,b,c; init_18b20(); write_18b20_dat(0xcc); write_18b20_dat(0x44); init_18b20(); write_18b20_dat(0xcc); write_18b20_dat(0xbe); a=read_18b20_dat(); b=read_18b20_dat(); c=a&0x0f; b<<=4; b+=(a&0xf0)>>4; return c; } /**************************** dht11函數(shù) *****************************/ void dht11_init(void) //dht11初始化復位函數(shù) { uchar i; for(i=0;i<8;i++) { flag=2; while((!DQ_shi)&&flag++); delay_dht11_D(2); tm=0; if(DQ_shi) tm=1; flag=2; while((DQ_shi)&&flag++); if(flag==1) break; dat<<=1; dat|=tm; } } uchar read_dht11(void) //dht11讀取濕度函數(shù) { uchar wet_L,temp_L,temp_H,wet_H,JY; DQ_shi=0; delay_dht11_C(180); DQ_shi=1; delay_dht11_D(4); DQ_shi=1; if(!DQ_shi) { flag=2; while((!DQ_shi)&&flag++); flag=2; while((DQ_shi)&&flag++); dht11_init(); wet_H=dat; dht11_init(); wet_L=dat; dht11_init(); temp_H=dat; dht11_init(); temp_L=dat; dht11_init(); JY=dat; DQ_shi=1; tm=(temp_H+temp_L+wet_H+wet_L); if(tm==JY) { temp=temp_H; wet=wet_H; } } return wet; } void chuli_wen_wet_light() //采集數(shù)據(jù)處理函數(shù) { uchar temp_zs,temp_xs,wet_zs; temp_zs=read_18b20_temp_zs(); //讀取18b20溫度整數(shù) temp_xs=read_18b20_temp_xs(); //讀取18b20溫度小數(shù) wet_zs=read_dht11(); //dht11濕度整數(shù) Huifu_wsg[6]=temp_zs%10+'0'; //數(shù)據(jù)轉(zhuǎn)化為字符存入字符數(shù)組 Huifu_wsg[5]=temp_zs/10+'0'; Huifu_wsg[9]=temp_xs%10+'0'; Huifu_wsg[8]=temp_xs/10+'0'; Huifu_wsg[17]=wet_zs%10+'0'; Huifu_wsg[16]=wet_zs/10+'0'; } void timer4() interrupt 4 using 1 { ES=0; //關(guān)串口中斷,防止中斷嵌套 if(TI) //如果是發(fā)送中斷,則不做任何處理 TI=0; //清除發(fā)送中斷標志位 if(RI) //如果是接送中斷,則進行處理 { RI=0; //清除接收中斷標志位 Huancun[i]=SBUF; //將接收到的字符串存到緩存中 i++; //緩存指針向后移動 if(i>200) //如果緩存滿,將緩存指針指向緩存的首地址 i=0; } ES = 1; //開啟串口中斷 }