W77E58在GPS远程定位的应用(源代码) .

来源:互联网 发布:c语言新建项目 编辑:程序博客网 时间:2024/06/06 17:02

转自:http://blog.csdn.net/ex_net/article/details/2765895

前段时间做测试写的程序,现在贴出来,供有兴趣的朋友参考交流。毕竟下来的程序里的部分代码也是来源于网络。所有现在贴出来回报网络。正因为有了网络,我才能进步。

      硬件要求: GPS模块、GSM短信模块(TC35/TC35i)或者兼容AT指令的其他模块、W77E58单片机(或者具备双串口的单片机)

/*
 说明:Winbond W77E58 双串口单片机
 时间:2008年7月3日
 程序:张建波
 串口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;
}

 

注意:相应的图纸,可以在我的博客中找到。欢迎有兴趣的朋友一起学习交流。