原创 AVR NMEA

2010-3-25 04:15 2018 3 3 分类: MCU/ 嵌入式


//MCU        Atmega128


#define  mclk   16000000


unsigned char speed_km[7]; //速度km/h
unsigned char JD[11];  //经度
unsigned char JD_a;   //经度方向
unsigned char WD[10];  //纬度
unsigned char WD_a;   //纬度方向
unsigned char date_y[5]={"2000"}; //年
unsigned char date_m[3]={"00"};  //月
unsigned char date_d[3]={"00"};  //日
unsigned char time_s[3]={"00"};  //时
unsigned char time_f[3]={"00"};  //分
unsigned char time_m[3]={"00"};  //秒
unsigned char speed[7];  //速度 1海里=1.852M/H
unsigned char high[8];  //高度
unsigned char DD[3];  //二维三维定位标志
unsigned char angle[6];  //方位角
unsigned char use_sat[3]; //使用的卫星数
unsigned char total_sat[4]; //天空中总卫星数
unsigned char DW[3];  //定位标志 V未定位 A已定位
//串口中断需要的变量
unsigned char seg_count;  //逗号计数器
unsigned char dot_count;  //小数点计数器
unsigned char byte_count;  //位数计数器
unsigned char cmd_number;  //命令类型
unsigned char mode;    //0:结束模式,1:命令模式,2:数据模式
volatile unsigned char buf_full;//1//:整句接收完成,相应数据有效。0:缓存数据无效。
unsigned char cmd[5];   //命令类型存储数组
//显示需要的变量
unsigned char dsp_count;  //刷新次数计数器
unsigned char time_count;      //?  
volatile unsigned char high_num,a_num,s_num;//?
//void init_set(void);//?


unsigned char direction[11];
unsigned char direction0[11];
unsigned int direction_int;
unsigned char direction_num;



void usart_Init(unsigned int baud)
{
   UCSR0B=0x00;
   UCSR0A=0x00;       //控制寄存器清零
   UCSR0C=(0<<UPM00)|(3<<UCSZ00);  
                                                        //选择UCSRC,异步模式,禁止                       
                                                     //   校验,1位停止位,8位数据位
   baud="mclk/16/baud-1" ;   //波特率最大为65K
   UBRR0L=baud;             
   UBRR0H=baud>>8;      //设置波特率
   UCSR0B=(1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0);
                                                       //接收、发送使能,接收中断使能
   SREG="BIT"(7);                 //全局中断开放
   DDRE|=BIT(1);                 //配置TX为输出(很重要)
         //总中断允许
}
//串口接收中断
void uart_rx0 (void)//串口0接收中断服务程序GPS
{
unsigned char tmp;
tmp=UDR0;
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;
    case 4:
     buf_full|=0x08;
     break;
    case 5:
     buf_full|=0x16;
     break;
                case 6:
     buf_full|=0x32;
     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]=='V'){
        if(cmd[3]=='T'){
         if(cmd[4]=='G'){
          cmd_number=6;
          mode="2";
          seg_count=0;
         }
        }
       }
                         if(cmd[2]=='G'){
        if(cmd[3]=='G'){
         if(cmd[4]=='A'){
          cmd_number=1;
          mode="2";
          seg_count=0;
          byte_count=0;
          high_num=0;
         }
        }
        else if(cmd[3]=='S'){
         if(cmd[4]=='V'){
          cmd_number=2;
          mode="2";
          seg_count=0;
          byte_count=0;
                                    }
         if(cmd[4]=='A'){
             cmd_number=5;
          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;
          a_num=0;
          s_num=0;
         }
        }
       }
       else if(cmd[2]=='Z'){
        if(cmd[3]=='D'){
         if(cmd[4]=='A'){
          cmd_number=4;
          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 7:        //定位使用的卫星数
        if(byte_count<2){
         use_sat[byte_count]=tmp;
        }
        break;
       case 9:        //高度处理
        if(byte_count<6){
         high[byte_count]=tmp;
         high_num++;
        }
        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<2){    //时间处理
                                 time_s[byte_count]=tmp;
        break;
        }
        if(byte_count<4){    //时间处理
        
                                 time_f[byte_count-2]=tmp;
        break;
        }
        if(byte_count<6){    //时间处理
        
                                 time_m[byte_count-4]=tmp;
        }
        break;
       case 2 :        //定位标志
        if(byte_count<1){
         DW[byte_count]=tmp;
           }
        break;
       case 7:        //速度处理,单位节,1节=1852M/H
        if(byte_count<5){
         speed[byte_count]=tmp;
         s_num++;
        }
        break;
       case 8:        //方位角处理
        if(byte_count<5){
         angle[byte_count]=tmp;
         //a_num++;
        }
        break;
       case 9:
        if(byte_count<2){    //时间处理
                                 date_d[byte_count]=tmp;
        break;
        }
        if(byte_count<4){    //时间处理
        
                                 date_m[byte_count-2]=tmp;
        break;
        }
        if(byte_count<6){    //时间处理
        
                                 date_y[byte_count-2]=tmp;
        }
        break;
      }
      break;
     case 4:    //类型4数据接收。GPZDA
      switch(seg_count){
       /*case 1:
        if(byte_count<2){    //时间处理
                                 time_s[byte_count]=tmp;
        break;
        }
        if(byte_count<4){    //时间处理
        
                                 time_s[byte_count]=tmp;
        break;
        }
        if(byte_count<6){    //时间处理
        
                                 time_s[byte_count]=tmp;
        }
        break;*/
       case 2:
        if(byte_count<2){
         date_d[byte_count]=tmp;
        }
        break;
       case 3:
        if(byte_count<2){
         date_m[byte_count]=tmp;
        }
        break;
       case 4:
        if(byte_count<4){
         date_y[byte_count]=tmp;
        }
        break;      
      }
      break;
     case 5:    //类型数据接收。GPGSA
      switch(seg_count){
       case 2:
        if(byte_count<1){    //二维三维定位标志处理
                                 DD[byte_count]=tmp;
        }
        break;
                     }
      break;
     case 6:    //类型数据接收。GPVTG
      switch(seg_count){
       case 7:
        if(byte_count<5){    //速度,单位KM/H
                                 speed_km[byte_count]=tmp;
        }
        break;
                     }
      break;
    }
   }
   byte_count++;  //接收数位加1
   break;
}
}



 
NMEA协议是为了在不同的GPS(全球定位系统)导航设备中建立统一的BTCM(海事无线电技术委员会)标准,由美国国家海洋电子协会(NMEA-The National Marine Electronics Associa-tion)制定的一套通讯协议。GPS接收机根据NMEA-0183协议的标准规范,将位置、速度等信息通过串口传送到PC机、PDA等设备。


NMEA-0183协议是GPS接收机应当遵守的标准协议,也是目前GPS接收机上使用最广泛的协议,大多数常见的GPS接收机、GPS数据处理软件、导航软件都遵守或者至少兼容这个协议。


NMEA-0183协议定义的语句非常多,但是常用的或者说兼容性最广的语句只有$GPGGA、$GPGSA、$GPGSV、$GPRMC、$GPVTG、$GPGLL等。下面给出这些常用NMEA-0183语句的字段定义解释。


$GPGGA


例:$GPGGA,092204.999,4250.5589,S,14718.5084,E,1,04,24.4,19.7,M,,,,0000*1F


字段0:$GPGGA,语句ID,表明该语句为Global Positioning System Fix Data(GGA)GPS定位信息


字段1:UTC 时间,hhmmss.sss,时分秒格式


字段2:纬度ddmm.mmmm,度分格式(前导位数不足则补0)


字段3:纬度N(北纬)或S(南纬)


字段4:经度dddmm.mmmm,度分格式(前导位数不足则补0)


字段5:经度E(东经)或W(西经)


字段6:GPS状态,0=未定位,1=非差分定位,2=差分定位,3=无效PPS,6=正在估算


字段7:正在使用的卫星数量(00 - 12)(前导位数不足则补0)


字段8:HDOP水平精度因子(0.5 - 99.9)


字段9:海拔高度(-9999.9 - 99999.9)


字段10:地球椭球面相对大地水准面的高度


字段11:差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空)


字段12:差分站ID号0000 - 1023(前导位数不足则补0,如果不是差分定位将为空)


字段13:校验值


$GPGSA


例:$GPGSA,A,3,01,20,19,13,,,,,,,,,40.4,24.4,32.2*0A


字段0:$GPGSA,语句ID,表明该语句为GPS DOP and Active Satellites(GSA)当前卫星信息


字段1:定位模式,A=自动手动2D/3D,M=手动2D/3D


字段2:定位类型,1=未定位,2=2D定位,3=3D定位


字段3:PRN码(伪随机噪声码),第1信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)


字段4:PRN码(伪随机噪声码),第2信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)


字段5:PRN码(伪随机噪声码),第3信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)


字段6:PRN码(伪随机噪声码),第4信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)


字段7:PRN码(伪随机噪声码),第5信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)


字段8:PRN码(伪随机噪声码),第6信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)


字段9:PRN码(伪随机噪声码),第7信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)


字段10:PRN码(伪随机噪声码),第8信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)


字段11:PRN码(伪随机噪声码),第9信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)


字段12:PRN码(伪随机噪声码),第10信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)


字段13:PRN码(伪随机噪声码),第11信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)


字段14:PRN码(伪随机噪声码),第12信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)


字段15:PDOP综合位置精度因子(0.5 - 99.9)


字段16:HDOP水平精度因子(0.5 - 99.9)


字段17:VDOP垂直精度因子(0.5 - 99.9)


字段18:校验值


$GPGSV


例:$GPGSV,3,1,10,20,78,331,45,01,59,235,47,22,41,069,,13,32,252,45*70


字段0:$GPGSV,语句ID,表明该语句为GPS Satellites in View(GSV)可见卫星信息


字段1:本次GSV语句的总数目(1 - 3)


字段2:本条GSV语句是本次GSV语句的第几条(1 - 3)


字段3:当前可见卫星总数(00 - 12)(前导位数不足则补0)


字段4:PRN 码(伪随机噪声码)(01 - 32)(前导位数不足则补0)


字段5:卫星仰角(00 - 90)度(前导位数不足则补0)


字段6:卫星方位角(00 - 359)度(前导位数不足则补0)


字段7:信噪比(00-99)dbHz


字段8:PRN 码(伪随机噪声码)(01 - 32)(前导位数不足则补0)


字段9:卫星仰角(00 - 90)度(前导位数不足则补0)


字段10:卫星方位角(00 - 359)度(前导位数不足则补0)


字段11:信噪比(00-99)dbHz


字段12:PRN 码(伪随机噪声码)(01 - 32)(前导位数不足则补0)


字段13:卫星仰角(00 - 90)度(前导位数不足则补0)


字段14:卫星方位角(00 - 359)度(前导位数不足则补0)


字段15:信噪比(00-99)dbHz


字段16:校验值


$GPRMC


例:$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50


字段0:$GPRMC,语句ID,表明该语句为Recommended Minimum Specific GPS/TRANSIT Data(RMC)推荐最小定位信息


字段1:UTC时间,hhmmss.sss格式


字段2:状态,A=定位,V=未定位


字段3:纬度ddmm.mmmm,度分格式(前导位数不足则补0)


字段4:纬度N(北纬)或S(南纬)


字段5:经度dddmm.mmmm,度分格式(前导位数不足则补0)


字段6:经度E(东经)或W(西经)


字段7:速度,节,Knots


字段8:方位角,度


字段9:UTC日期,DDMMYY格式


字段10:磁偏角,(000 - 180)度(前导位数不足则补0)


字段11:磁偏角方向,E=东W=西


字段16:校验值


$GPVTG


例:$GPVTG,89.68,T,,M,0.00,N,0.0,K*5F


字段0:$GPVTG,语句ID,表明该语句为Track Made Good and Ground Speed(VTG)地面速度信息


字段1:运动角度,000 - 359,(前导位数不足则补0)


字段2:T=真北参照系


字段3:运动角度,000 - 359,(前导位数不足则补0)


字段4:M=磁北参照系


字段5:水平运动速度(0.00)(前导位数不足则补0)


字段6:N=节,Knots


字段7:水平运动速度(0.00)(前导位数不足则补0)


字段8:K=公里/时,km/h


字段9:校验值


$GPGLL


例:$GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D


字段0:$GPGLL,语句ID,表明该语句为Geographic Position(GLL)地理定位信息


字段1:纬度ddmm.mmmm,度分格式(前导位数不足则补0)


字段2:纬度N(北纬)或S(南纬)


字段3:经度dddmm.mmmm,度分格式(前导位数不足则补0)


字段4:经度E(东经)或W(西经)


字段5:UTC时间,hhmmss.sss格式


字段6:状态,A=定位,V=未定位


字段7:校验值


转自http://bbs.dspoz.com/viewthread.php?tid=158

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条