硬件要求: GPS模块、GSM短信模块(TC35/TC35i)或者兼容AT指令的其他模块、W77E58单片机(或者具备双串口的单片机)
/*
说明:Winbond W77E58 双串口单片机
串口0 采用9600波特率
串口1 采用4800波特率
*/
#include "w77e58.h"
#include "string.h"
static int flag_1,flag_0;
//char c1[]="hello china"; //串口0
//char c2[]="hello World"; //串口1
//串口0 9600 8 N 1
//串口1 4800 8 N 1
//GSM 数据存储数组
unsigned char PhoneNum[12]; //手机号码
unsigned char smsCmd[2]; //短信命令
unsigned char smsPWD[8]; //密码(在绑定指定号码时,需要)
unsigned char sms_count; //短信长度
unsigned char sms[25]; //短信内容 "*SZ12345678#13577062679#";
unsigned char sms_mode; //当前短信接收,=1 正在接收 =0 命令语句接收是否完毕
//unsigned char CNMI[]="AT+CNMI=2,2,0,0/r/n";//每次接收短信后,再设置,不然不会再有短信进取
//unsigned char CMGF[]="AT+CMGF=1/r/n"; //是以TEXT格式发送
//GPS ----
//GPS数据存储数组
unsigned char JD[10]; //经度
unsigned char JD_a; //经度方向
unsigned char WD[9]; //纬度
unsigned char WD_a; //纬度方向
unsigned char time[6]; //时间
unsigned char speed[5]; //速度
unsigned char high[6]; //高度
unsigned char angle[5]; //方位角
unsigned char use_sat[2]; //使用的卫星数
unsigned char total_sat[2]; //天空中总卫星数
unsigned char lock; //定位状态
//串口中断需要的变量
unsigned char seg_count; //逗号计数器
unsigned char dot_count; //小数点计数器
unsigned char byte_count; //位数计数器
unsigned char cmd_number; //命令类型
unsigned char mode; //0:结束模式,1:命令模式,2:数据模式
unsigned char buf_full; //1:整句接收完成,相应数据有效。0:缓存数据无效。
unsigned char cmd[5]; //命令类型存储数组
//------
//状态指示灯
sbit P0_0=P0^0;
sbit P0_1=P0^1;
sbit P0_2=P0^2;
sbit P0_3=P0^3;
sbit P0_4=P0^4;
sbit P0_5=P0^5;
sbit P0_6=P0^6;
sbit P0_7=P0^7;
//-----------------
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
//向串口发送一个字符
void send_char_com0(unsigned char ch)
{
SBUF=ch;
while(TI==0);
TI=0;
}
void init_GSM(void)
{
//系统初始化
//初始化 GSM
// AT+CMGF=1是以TEXT格式发送
send_char_com0('A');
send_char_com0('T');
send_char_com0('+');
send_char_com0('C');
send_char_com0('M');
send_char_com0('G');
send_char_com0('F');
send_char_com0('=');
send_char_com0('1');
send_char_com0('/r');
send_char_com0('/n');
Delay400Ms();
Delay400Ms();
Delay400Ms();
//Delay400Ms();
//Delay400Ms();
//AT+CNMI=2,2,0,0 //每次接收短信后,再设置,不然不会再有短信进取
send_char_com0('A');
send_char_com0('T');
send_char_com0('+');
send_char_com0('C');
send_char_com0('N');
send_char_com0('M');
send_char_com0('I');
send_char_com0('=');
send_char_com0('2');
send_char_com0(',');
send_char_com0('2');
send_char_com0(',');
send_char_com0('0');
send_char_com0(',');
send_char_com0('0');
send_char_com0('/r');
send_char_com0('/n');
}
void SendSM(char *s)
{
int i=0;
do{
if(s[i]!='$')
{
send_char_com0(s[i]);
}
i++;
}while(s[i]!='$');
}
main()
{
// int i;
int j=0;
flag_1=1;
flag_0=1;
for(j=0;j<5;j++)
{
P0_0=~P0_0;
P0_1=~P0_1;
P0_2=~P0_2;
P0_3=~P0_3;
P0_4=~P0_4;
P0_5=~P0_5;
P0_6=~P0_6;
P0_7=~P0_7;
Delay400Ms();
Delay400Ms();
}
P0_0=1;
P0_1=1;
P0_2=1;
P0_3=1;
P0_4=1;
P0_5=1;
P0_6=1;
P0_7=1;
//其中串口0用定时器2,串口1用定时器1
//串口1的设置
IE=0x90; //允许总中断和串口0的中断
TMOD=0x20; //定时器1工作在模式1
TL1=0xfa; //baud rate=4800
TH1=0xfa;
SCON=0x58; //工作在模式1,接收允许
PCON=0x00; // SM0=0 SM1=1 在10位异步收发模式 SMOD=0 溢出速率/32
ES1=1; //串口1中断允许
//串口0设置
T2CON=0x30; //用定时器2做串口0的波特率发生器
RCAP2H=0xff; // 11.0592M晶振下,baud rate=9600 //2400
RCAP2L=0xdc; //0x70;
SCON1=0x58; //工作在模式1,允许接收
TR2=1;
TR1=1;
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
init_GSM(); //初始化GSM 猫
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
for(j=0;j<5;j++)
{
P0_0=~P0_0;
P0_1=~P0_1;
P0_2=~P0_2;
P0_3=~P0_3;
P0_4=~P0_4;
P0_5=~P0_5;
P0_6=~P0_6;
P0_7=~P0_7;
Delay400Ms();
Delay400Ms();
}
while(1)
{
//查询新短信
//AT+CMGL
if(sms_mode!=-1){
send_char_com0('A');send_char_com0('T');send_char_com0('+');send_char_com0('C');send_char_com0('M');send_char_com0('G');send_char_com0('L');
send_char_com0('/r');send_char_com0('/n');
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
}
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
if(buf_full==0) //无GPS信号时
{
P0_0=1; //1表示没有信号
}else
{
P0_0=0; //有信号
if(buf_full|0x01)
{
//GGA语句
if(lock=='0')
{
//如果未定位
P0_0=1;
}else
{
//如果已定位
P0_0=0;
}
}
}
}
}
void fw(void)
{
//复位GSM
//init_GSM();//复位GSM MODEM
}
void dw(void)
{
//GPS 定位
int i;
for(i=0;i<10;i++)
{
P0_0=~P0_0;
P0_1=~P0_1;
P0_2=~P0_2;
P0_3=~P0_3;
Delay400Ms();
Delay400Ms();
}
//init_GSM();//复位GSM MODEM
//sms_mode=-1; //定位
//SendSM("AT+CMGS=/"+8613577062697/"/r/n$");
SendSM("AT+CMGS=/"+86$");
for(i=0;i<11;i++)
{
send_char_com0(PhoneNum[i]);
}
SendSM("/"/r/n$");
Delay400Ms();
Delay400Ms();
/*定位数据*/
/*
send_char_com0(JD_a);//经度方向
for(i=0;i<10;i++)
{
send_char_com0(JD[i]);//经度
}
send_char_com0(WD_a);//纬度方向
for(i=0;i<9;i++)
{
send_char_com0(WD[i]);//纬度
}
send_char_com0('T'); //时间
for(i=0;i<6;i++)
{
send_char_com0(time[i]);//纬度
}
send_char_com0('S'); //速度
send_char_com0('P'); //速度
for(i=0;i<5;i++)
{
send_char_com0(speed[i]);//速度
}
send_char_com0('^'); //方位角
for(i=0;i<5;i++)
{
send_char_com0(angle[i]);//速度
}
*/
/*定位数据*/
/*----------------------*/
send_char_com0('M');
send_char_com0('i');
send_char_com0('o');
send_char_com0('_');
send_char_com0('C');
send_char_com0('H');
send_char_com0('S');
send_char_com0('#');
send_char_com0(JD_a);//经度方向
for(i=0;i<2;i++)
{
send_char_com0(JD[i]);//经度
}
send_char_com0(0x60);//度
for(i=3;i<2;i++)
{
send_char_com0(JD[i]);//经度
}
send_char_com0(''');//经度
for(i=3;i<2;i++)
{
send_char_com0(JD[i]);//经度
}
send_char_com0('"');//经度
send_char_com0('#');
send_char_com0(WD_a);//纬度方向
for(i=0;i<9;i++)
{
send_char_com0(WD[i]);//纬度
}
send_char_com0('#');
send_char_com0('#');
send_char_com0('#');
send_char_com0('M');
send_char_com0('i');
send_char_com0('o');
send_char_com0('S');
send_char_com0('M');
send_char_com0('S');
send_char_com0('#');
/**/
SBUF=0x1A;
while(TI==0);
TI=0;
}
void sz(void)
{
//绑定手机号码
int i;
for(i=0;i<10;i++)
{
P0_4=~P0_4;
P0_5=~P0_5;
P0_6=~P0_6;
P0_7=~P0_7;
Delay400Ms();
Delay400Ms();
//---
smsPWD[0]=sms[3];
smsPWD[1]=sms[4];
smsPWD[2]=sms[5];
smsPWD[3]=sms[6];
smsPWD[4]=sms[7];
smsPWD[5]=sms[8];
smsPWD[6]=sms[9];
smsPWD[7]=sms[10];
//--
PhoneNum[0]=sms[12]; //1
PhoneNum[1]=sms[13]; //3
PhoneNum[2]=sms[14]; //5
PhoneNum[3]=sms[15]; //7
PhoneNum[4]=sms[16]; //7
PhoneNum[5]=sms[17]; //0
PhoneNum[6]=sms[18]; //6
PhoneNum[7]=sms[19]; //2
PhoneNum[8]=sms[20]; //6
PhoneNum[9]=sms[21]; //7
PhoneNum[10]=sms[22]; //9
//--
}
//SendSM("AT+CMGS=/"+8613577062697/"/r/n$");
SendSM("AT+CMGS=/"+86$");
for(i=0;i<11;i++)
{
send_char_com0(PhoneNum[i]);
}
SendSM("/"/r/n$");
Delay400Ms();
Delay400Ms();
send_char_com0('B');
send_char_com0('D');
for(i=0;i<12;i++)
{
send_char_com0(PhoneNum[i]);
}
send_char_com0('#');
for(i=0;i<8;i++)
{
send_char_com0(smsPWD[i]);
}
send_char_com0('#');
//SendSM("SYSTEM$");
SBUF=0x1A;
while(TI==0);
TI=0;
// sms_mode=-1;
// init_GSM();//复位GSM MODEM
}
void serial_0(void)interrupt 4
{
// GSM 短信猫
unsigned char tmp;
if(RI)
{
tmp=SBUF;
switch(tmp)
{
//忽略 +CMT: "+8613577062697",,"08/07/04,21:26:44+32"
case '+':
sms_count=0;
sms_mode=0;
break;
case '"':
sms_count=0;
sms_mode=0;
break;
case '>': //短信发送模式
sms_count=0;
sms_mode=-1;
break;
case '*':
sms_count=0; //接收位清空
sms_mode=1;
break;
case 'O': //OK
{
if(sms_mode==-1)
{
//段信发送成功
sms_mode=0;
sms_count=0;
}
break;
}
default:
if(sms_mode==1)
{
sms[sms_count++]=tmp;
if(tmp=='%')
{
sms_mode=2; //命令语句接收完毕
//开始处理
switch(sms[0])
{
case 'D': //DW 进行GPS定位
sms_mode=-1;
dw();
break;
case 'S': //SZ 进行手机号码绑定
sms_mode=-1;
sz();
break;
default:
fw(); //复位GSM
break;
}
}
}
break;
}
RI=0;
}
// if(TI)
// {
// TI=0;
// }
}
void serial_1(void)interrupt 7
{
unsigned char tmp;
if(RI_1)
{
P0_7=~P0_7;
tmp=SBUF1;
switch(tmp)
{
case '$':
cmd_number=0; //命令类型清空
mode=1; //接收命令模式
byte_count=0; //接收位数清空
break;
case ',':
seg_count++; //逗号计数加1
byte_count=0;
break;
case '*':
switch(cmd_number)
{
case 1:
buf_full|=0x01;
break;
case 2:
buf_full|=0x02;
break;
case 3:
buf_full|=0x04;
break;
}
mode=0;
break;
default:
if(mode==1)
{
//命令种类判断
cmd[byte_count]=tmp; //接收字符放入类型缓存
if(byte_count>=4)
{ //如果类型数据接收完毕,判断类型
if(cmd[0]=='G')
{
if(cmd[1]=='P')
{
if(cmd[2]=='G')
{
if(cmd[3]=='G')
{
if(cmd[4]=='A')
{
cmd_number=1;
mode=2;
seg_count=0;
byte_count=0;
}
}
else if(cmd[3]=='S')
{
if(cmd[4]=='V')
{
cmd_number=2;
mode=2;
seg_count=0;
byte_count=0;
}
}
}
else if(cmd[2]=='R')
{
if(cmd[3]=='M')
{
if(cmd[4]=='C')
{
cmd_number=3;
mode=2;
seg_count=0;
byte_count=0;
}
}
}
}
}
}
}
else if(mode==2)
{
//接收数据处理
switch (cmd_number)
{
case 1: //类型1数据接收。GPGGA
switch(seg_count)
{
case 2: //纬度处理
if(byte_count<9)
{
WD[byte_count]=tmp;
}
break;
case 3: //纬度方向处理
if(byte_count<1)
{
WD_a=tmp;
}
break;
case 4: //经度处理
if(byte_count<10)
{
JD[byte_count]=tmp;
}
break;
case 5: //经度方向处理
if(byte_count<1)
{
JD_a=tmp;
}
break;
case 6: //定位判断
if(byte_count<1)
{
lock=tmp;
}
break;
case 7: //定位使用的卫星数
if(byte_count<2)
{
use_sat[byte_count]=tmp;
}
break;
case 9: //高度处理
if(byte_count<6)
{
high[byte_count]=tmp;
}
break;
}
break;
case 2: //类型2数据接收。GPGSV
switch(seg_count)
{
case 3: //天空中的卫星总数
if(byte_count<2)
{
total_sat[byte_count]=tmp;
}
break;
}
break;
case 3: //类型3数据接收。GPRMC
switch(seg_count)
{
case 1:
if(byte_count<6)
{ //时间处理
time[byte_count]=tmp;
}
break;
case 7: //速度处理
if(byte_count<5)
{
speed[byte_count]=tmp;
}
break;
case 8: //方位角处理
if(byte_count<5)
{
angle[byte_count]=tmp;
}
break;
}
break;
}
}
byte_count++; //接收数位加1
break;
}
}
RI_1=0;
}