⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gprs.c

📁 单片机数据通讯典型应用(光盘内容)
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <reg52.h>
#include <stdio.h>

//****************************************************************************
//****************************宏定义******************************************
//****************************************************************************
#define  uchar  unsigned char
#define  uint   unsigned int
#define  OLEN  20                        //发送缓冲区大小
#define  ILEN  500                       //接收缓冲区大小

//****************************************************************************
//**************************变量定义******************************************
//****************************************************************************
sfr     WDT_CONTR=0xe1;       //看门狗寄存器

uchar   n,i,j,ch;
uchar   CMP_flag;             //接收数据帧类型
uchar   SISW[2];
uchar tt;
uchar  xdata     outbuf[OLEN];       //定义发送缓冲区
uchar  xdata     *outlast=outbuf;    //最后由中断传输出去的字节位置
uchar  xdata     *putlast=outbuf;    //最后放入发送缓冲区的字节位置

uchar  xdata     inbuf[ILEN];        //定义接收缓冲区
uchar  xdata     *inlast=inbuf;      //最后由中断进入接收缓冲区的字节位置
uchar  xdata     *getlast=inbuf;     //最后取走的字节位置

uchar  xdata     phone_obj[12];      //对方的手机号码
uchar  xdata     IP_self_buf[26];    //自己的IP地址缓冲区
uchar  xdata     IP_obj_buf[26];     //对方的的IP地址缓冲区
uchar  xdata     *IP_self=IP_self_buf,*IP_obj=IP_obj_buf;
                                            //自己的IP地址、对方的IP地址

//*****************位变量定义*********************
sbit P1_0=P1^0;
sbit P1_1=P1^1;
sbit P1_2=P1^2;
sbit P1_3=P1^3;
sbit P1_4=P1^4;
sbit P1_5=P1^5;
sbit P1_6=P1^6;
sbit P1_7=P1^7;
sbit P3_1=P3^1;
sbit P3_0=P3^0;

bit  outbufsign0;                   //最后一个数据发完标志  发完=0
bit  outbufsign;                    //输出缓冲区非空标志    有=1
bit  inbufsign;                     //接收缓冲区非空标志    有=1
bit  inbufful;                      //输入缓冲区满标志      满=1
bit  Wait_t0=0;                     //定时时间到标志
bit  Wait_RI=0;                     //数据到达标志
bit  int1_RI=0;                     //外部中断数据到达标志
//****************************************************************************
//**************************函数声明******************************************
//****************************************************************************
void delay(uint time);                //延时函数
void serl_init(void);                 //串口初始化
void module_init(void);               //模块初始化
void IGT_target(void);                //启动模块
void conn_module(void);               //模拟开关连接到模块
void conn_485(void);                  //模拟开关连接到485总线
void SMS_set(void);                   //设置短消息参数
void delete_all_sms(void);            //删除全部短消息
void TCP_set(void);                   //设置GPRS参数
void close_conn(void);                //关闭上次连接
void send_SMS(uchar *phone);          //给客户端发送短信,告知自己的ip
void send_SISW(void);                 //发送AT^SISW=Srvprofile,length
void build_srvprofile(uchar srvprofileID,uchar *IP_remove);//建立服务层 

void putbyte(uchar c);                //放入一个字节到发送缓冲区
void send_str(uchar  *puts);          //发送字符串
uchar getbyte(void);                  //从接收缓冲区取一个字节的数据
void clear_inbuf(void);               //清空接收缓冲区
void Wait_clear_inbuf(void);          //等待接收完一帧数据后清空接收缓冲区,并延时大于100ms

//****************************************************************************
//****************************主函数******************************************
//****************************************************************************
main()
{
    serl_init();                        //串口初始化
    conn_module();                      //模拟开关连接到模块
/*
   send_str("AT^SMSO\r\0");            //关闭模块
    for(i=0;i<300;i++)
    {
      delay(60000);
    } 

*/
    IGT_target();                       //启动模块
    for(tt=0;tt<15;tt++)
    {
      delay(60000);
      WDT_CONTR=0x3e;
    }
/*
for(tt=0;tt<100;tt++)
    {
      inbuf[tt]=0;
    }*/
    module_init();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     //模块初始化
    SMS_set();                       //设置短消息参数
    //delete_all_sms();                //删除全部短消息
    TCP_set();                       //设置GPRS参数,从移动网关获得自己的IP地址
    delay(20000);
    conn_485();                      //模拟开关连接到485总线
    send_str("Initiation over!\r\n\0");//模块初始化结束
    delay(4000);
    conn_module();                     //模拟开关连接到模块
    

//********************侦听有无数据到达**********************
 while(1)
 {
  clear_inbuf();
  while(!Wait_RI)        //等待接收数据
  {
   WDT_CONTR=0x3e;
  }             
  Wait_RI=0;
  conn_module();                      //模拟开关连接到模块
  
//**********************************************************
 if((inbuf[0]=='A')&&(inbuf[1]=='T'))
     {
       CMP_flag=0;     //AT指令
     }
     else if((inbuf[0]=='\r')&&(inbuf[1]=='\n')) 
          {
           CMP_flag=1;     //返回码
          }
          else
           { 
           CMP_flag=2;     //数据流
           } 
 //**********************************************************
 
  switch(CMP_flag)                      //判断数据类型
   {
     case 0:       //AT指令,PC机发送电话号码以ATM开头
      if((inbuf[0]=='A')&&(inbuf[1]=='T')&&(inbuf[2]=='M')&&(int1_RI==1))
      {
        int1_RI=0;
        WDT_CONTR=0x3e;                       //喂狗
        for(ch=0;ch<11;ch++)
         {
          phone_obj[ch]=inbuf[ch+3];
         }
        phone_obj[11]='\0';                    //使电话号码以\0结束
        close_conn();                          //关闭上次连接  
        send_SMS(phone_obj);                   //给客户端发送短信,告知自己的ip。
        WDT_CONTR=0x3e;                        //喂狗
        delay(30000);   
      }
     break;
     
     case 1:  

    //接收短信息,存储对方IP,并把自己的IP发给对方。
   if((inbuf[2]=='+')&&(inbuf[3]=='C')&&(inbuf[4]=='M')&&(inbuf[5]=='T'))
     {
      WDT_CONTR=0x3e;                    //喂狗
      while(inbufsign)
      {
       ch=getbyte();
       if(ch=='%')
         break;
      }
         
    if(ch=='%')
      { 
        EA=0;
        for(ch=0;inbufsign;ch++)
         {
          IP_obj_buf[ch]=getbyte();
          if(IP_obj_buf[ch]=='!')
           { 
            IP_obj_buf[ch]='\0';    //IP地址以\0结尾,作为一个字符串
            break;
           }
         } 
        
        IP_obj=IP_obj_buf;     //IP_obj指向对方的IP地址,作为一个字符串
        EA=1;  
        WDT_CONTR=0x3e;                    //喂狗            
        delay(30000);
        send_str("AT+CNMA\r\0");  //AT+CNMA用于应答ME,表示自己成功接受到短信
        Wait_clear_inbuf(); 
        
        build_srvprofile('5',IP_obj);  //建立一个服务层
      }
  }
  
//**********************************************************************
//************收到^SISR:<srv>,<causeID>*********************************
//**********************************************************************
  if((inbuf[2]=='^')&&(inbuf[3]=='S')&&(inbuf[4]=='I')&&(inbuf[5]=='S')&&(inbuf[6]=='R'))
  {    
      if(inbuf[12]=='0') //无数据可以读
     { 
        conn_485();                      //模拟开关连接到485总线
        send_str("No data available for reading!\r\n\0");
        delay(4000);
        conn_module();                      //模拟开关连接到模块  
     }
     if(inbuf[12]=='1')   //表示有数据可以读
     {
            WDT_CONTR=0x3e;                    //喂狗
            conn_485();                      //模拟开关连接到485总线
            send_str("New data is coming!\r\n\0"); 
            delay(4000);  
            conn_module();                      //模拟开关连接到模块
            ES=0;
            TI=1;
            printf("AT^SISR=%c,400\r",inbuf[9]);    //提取模块数据指令
            TI=0;
            ES=1;
            WDT_CONTR=0x3e;
            
             clear_inbuf();
             delay(30000);
             while(!Wait_RI)        //等待接收数据
             {
              WDT_CONTR=0x3e;
             } 
             Wait_RI=0;

             do{
                if(inbufsign)
	              i=getbyte();
                else
                  break;
              }while(i!=':');
            if(i==':')                        //收到^SISR:<srv>,<causeID>
             {
               inlast--; 
           	   inlast--;  
               inlast--; 
               if(*inlast=='K')
                {
                 do{
                    i=getbyte();                           
                   }while(i!=0x0a);                 //等换行符
              
                 inlast--;
                 inlast--; 
                 inlast--;
                 *inlast='\0';                   //把收到的数据转换为字符串发送
           
                 conn_485();                      //模拟开关连接到485总线,发送数据给PC
                 send_str(getlast);               //发送数据到PC
                 WDT_CONTR=0x3e;                    //喂狗
                 delay(30000);
                 conn_module();                      //模拟开关连接到模块      
                 inbuf[2]=0;  
                } 
               else
                {
                 conn_485();                      //模拟开关连接到485总线
                 send_str("Error data!\r\n\0"); 
                 delay(4000);  
                 conn_module();                      //模拟开关连接到模块
                } 
             } 
       }
       
       if(inbuf[12]=='2')   //表示数据已经接收完毕
       {
         conn_485();                      //模拟开关连接到485总线
         send_str("All data have been read!\r\n\0");
         delay(4000);
         conn_module();                      //模拟开关连接到模块
       }
   }
//*********************************************************************
//************收到^SIS:<srv>,<URCcause>,<URCInfoID>********************
//*********************************************************************
  if((inbuf[2]=='^')&&(inbuf[3]=='S')&&(inbuf[4]=='I')&&(inbuf[5]=='S')&&(inbuf[6]==':'))
  {
          WDT_CONTR=0x3e;
  		  if(inbuf[11]=='1')//表示远端有连接,接受或拒绝
  		  {
   			ES=0;
   			TI=1;
   			printf("AT^SISO=%c\r",inbuf[14]);
   			TI=0;
   	        ES=1; 
   	        
   	        while(!Wait_RI)        //等待接收数据
            {
             WDT_CONTR=0x3e;
            } 
            Wait_RI=0;
            do{
              if(inbufsign)
	            i=getbyte();
              else
                 break;       //如果没有OK,跳出循环
              }while(i!='K'); 
           clear_inbuf();  
   	        
   	      }    	   
 	    else    //表示有错误,关闭并清空此服务层。inbuf[11]为<URCcause>
          {
            conn_485();                      //模拟开关连接到485总线
            send_str("Connection error,connection is closed!\r\n\0");
            delay(5000);
            conn_module();                      //模拟开关连接到模块
            WDT_CONTR=0x3e;                    //喂狗
   			ES=0;
   			TI=1;
   			printf("AT^SISC=%c\r",inbuf[8]);  //关闭服务层
   			
   	        delay(50000);
   	        WDT_CONTR=0x3e;
   	        printf("AT^SISS=%c,\"srvType\",\"none\"\r",inbuf[8]); 
   	                                           //清空此服务层,以便以后重新分配
   	        TI=0; 
   	        ES=1;
   	        delay(50000);
   	        while(!Wait_RI)        //等待接收数据
            {
             WDT_CONTR=0x3e;
            } 
   	        Wait_RI=0;
   	        inbuf[2]=0;
          }
    }
   //**********************************************************************
   //************收到^SISW:<srv>,<causeID>*********************************
   //**********************************************************************
	if((inbuf[2]=='^')&&(inbuf[3]=='S')&&(inbuf[4]=='I')&&(inbuf[5]=='S')&&(inbuf[6]=='W'))
	 {
	   WDT_CONTR=0x3e;                    //喂狗
 	   if(inbuf[12]=='1')
 	   {
 	    SISW[0]=inbuf[9];
 	    SISW[1]=inbuf[12];
 	    inbuf[2]=0;
 	    conn_485();                      //模拟开关连接到485总线
        send_str("Data can be written!\r\n\0");
        delay(4000);
        conn_module();                      //模拟开关连接到模块
       } 
      if(inbuf[12]=='0')
       {
        inbuf[2]=0;
        conn_485();                      //模拟开关连接到485总线
        send_str("No data can be written!\r\n\0");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -