專注電子技術(shù)學習與研究
當前位置:單片機教程網(wǎng) >> MCU設(shè)計實例 >> 瀏覽文章

基于GSM模塊的大棚環(huán)境參數(shù)傳輸與控制

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2012年01月02日   【字體:
/**********************************************
 設(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;                        //開啟串口中斷
}
關(guān)閉窗口

相關(guān)文章