📄 gprs.c
字号:
#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 + -