溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

GPS(NMEA)數(shù)據(jù)解析

發(fā)布時(shí)間:2020-07-15 00:34:51 來(lái)源:網(wǎng)絡(luò) 閱讀:3267 作者:Linux_woniu 欄目:系統(tǒng)運(yùn)維

一、GPS定位信息

設(shè)置好gps模式,啟動(dòng)gps,正常的話在gps通路有NMEA數(shù)據(jù)上報(bào),如下:

$GPGSV,3,1,11,01,62,130,42,07,61,201,43,11,72,075,28,17,20,251,38*7A

$GPGSV,3,2,11,30,63,272,44,03,00,149,,08,34,046,,13,05,309,*76

$GPGSV,3,3,11,22,08,127,,27,03,057,,28,34,312,*4C

$GPGGA,042523.0,3413.610533,N,10854.063257,E,1,05,2.6,438.5,M,-28.0,M,,*78

$GPVTG,245.9,T,245.9,M,0.0,N,0.0,K,A*23

$GPRMC,042523.0,A,3413.610533,N,10854.063257,E,0.0,245.9,190716,0.0,E,A*0F

$GPGSA,A,2,01,07,11,17,30,,,,,,,,2.8,2.6,1.0*3F

(1) $GPGGA (GPS定位信息)

  協(xié)議格式:

$GPGGA,161229.487,3723.2475,N,12158.3416,W,1,07,1.0,9.0,M, , ,,0000*18

 協(xié)議格式詳細(xì)分析:

GPS(NMEA)數(shù)據(jù)解析

(2) $GPGLL (地理定位信息)

  協(xié)議格式:

$GPGLL,<1>,<2>,<3>,<4>,<5>,<6>*hh<CR><LF>

樣例數(shù)據(jù):

$GPGLL,3723.2475,N,12158.3416,W,161229.487,A*2C

協(xié)議格式詳細(xì)分析:

GPS(NMEA)數(shù)據(jù)解析

(3) $GPGSA (當(dāng)前衛(wèi)星信息)

  協(xié)議格式:

$GPGSA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>,<13>,<14>,<15>,<16>,<17>*hh<CR><LF>

樣例數(shù)據(jù):

$GPGSA,A,3,07,02,26,27,09,04,15, , , , , ,1.8,1.0,1.5*33

協(xié)議格式詳細(xì)分析:

GPS(NMEA)數(shù)據(jù)解析

GPS(NMEA)數(shù)據(jù)解析

(4) $GPGSV(可見衛(wèi)星信息)

 協(xié)議格式:
$GPGSV, <1>,<2>,<3>,<4>,<5>,<6>,<7>,...,<4>,<5>,<6>,<7>*hh<CR><LF>

樣例數(shù)據(jù):

$GPGSV,2,1,07,07,79,048,42,02,51,062,43,26,36,256,42,27,27,138,42*71$GPGSV,2,2,07,09,23,313,42,04,19,159,41,15,12,041,42*41

需要注意的是這里的樣例數(shù)據(jù)有2條,這是因?yàn)楫?dāng)前可見衛(wèi)星一共有7個(gè),但是每條語(yǔ)句最多包括四顆衛(wèi)星的信息,所以分成了2條語(yǔ)句。每顆衛(wèi)星的信息有四個(gè)數(shù)據(jù)項(xiàng),即:<4>(衛(wèi)星編號(hào))、<5>(衛(wèi)星仰角)、<6>(衛(wèi)星方位角)、<7>(信噪比)。

  協(xié)議格式詳細(xì)分析(只分析第1條樣例數(shù)據(jù)語(yǔ)句):

GPS(NMEA)數(shù)據(jù)解析

(5) $GPRMC(最簡(jiǎn)定位信息)

  協(xié)議格式:

$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>*hh<CR><LF>

樣例數(shù)據(jù):

$GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13,309.62,120598,,*10

協(xié)議格式詳細(xì)分析:

GPS(NMEA)數(shù)據(jù)解析

(6) $GPVTG(地面速度信息)

  協(xié)議格式:

$GPVTG,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>*hh<CR><LF>

樣例數(shù)據(jù):

$GPVTG,309.62,T, ,M,0.13,N,0.2,K*6E

協(xié)議格式詳細(xì)分析:

GPS(NMEA)數(shù)據(jù)解析

二、GPS(NMEA)數(shù)據(jù)解析

/*********************************************************************************/

ingps.h

/*********************************************************************************/

#include<stdio.h>  

#include<stdlib.h>  

#include<string.h>  

#include<sys/types.h>  

#include<sys/stat.h>  

#include<fcntl.h>  

#include<unistd.h>  

#include<termios.h>  

#include<string.h> 

/*********************************************************************************/

degps.h

/*********************************************************************************/

#include "ingps.h"

#define TTYUSB "/dev/ttyUSB3"  /*串口設(shè)備*/ 

#define BAUD_RATE 4800      /*波特率 */

#define DATA_BITS 8     /*數(shù)據(jù)位*/ 

#define NEVENT 'N'       /*校驗(yàn) */

#define NSTOP 1         /*停止位*/ 

#define BUFLEN 512       /*可隨意取,但要大于GPGGA_MAX*/

#define GPGGA_MAX 100       /*"$GPGGA……"的最大值,待定*/ 

#define DBG_GPS


typedef struct{  

    int year;    

    int month;   

    int day;  

    int hour;  

    int minute;  

    int second;  

}date_time;  

  

typedef struct{  

     date_time D;/*時(shí)間*/  

     char status;       /*接收狀態(tài) */

     double latitude;   /*緯度*/  

     double longitude;  /*經(jīng)度 */ 

     char NS;           /*南北極*/  

     char EW;           /*東西 */ 

     int num;           /*衛(wèi)星數(shù)*/ 

     double speed;      /*速度 */ 

     double high;       /*高度*  

}GPS_INFO;

/*********************************************************************************/

getgps.c

/*********************************************************************************/

#include “degps.h”

#include "ingps.h"


static int GetComma(int num,char *str)  

{  

    int i,j=0;  

    int len=strlen(str); 

    for(i=0;i<len;i++)  

    {  

        if(str[i]==',')

        j++;  

        if(j==num)

        return i+1;   /*返回當(dāng)前找到的逗號(hào)位置的下一個(gè)位置*/  

    }  

    return 0;     

}


static double get_double_number(char *s)  

{  

    char buf[128];  

    int i;  

    double rev;  

    i=GetComma(1,s);    /*得到數(shù)據(jù)長(zhǎng)度 */

    strncpy(buf,s,i);  

    buf[i]=0;           /*加字符串結(jié)束標(biāo)志*/ 

    rev=atof(buf);      /*字符串轉(zhuǎn)float */ 

    return rev;  

}


static int get_int_number(char *s)  

{  

    char buf[128];  

    int i;  

    double rev;  

    i=GetComma(1,s);    /*得到數(shù)據(jù)長(zhǎng)度*/  

    strncpy(buf,s,i);  

    buf[i]=0;           /*加字符串結(jié)束標(biāo)志 */

    rev=atoi(buf);      /*字符串轉(zhuǎn)float */ 

    return rev;  

}

static void UTC2BTC(date_time *GPS)  

{  

/*如果秒號(hào)先出,再出時(shí)間數(shù)據(jù),則將時(shí)間數(shù)據(jù)+1秒 */ 

GPS->second++; /*加一秒*/  

if(GPS->second>59){  

GPS->second=0;  

GPS->minute++;  

if(GPS->minute>59){  

GPS->minute=0;  

GPS->hour++;  

}  

}     

GPS->hour+=8;        /*北京時(shí)間跟UTC時(shí)間相隔8小時(shí) */ 

if(GPS->hour>23)  

{  

GPS->hour-=24;  

GPS->day+=1;  

if(GPS->month==2 ||GPS->month==4 ||GPS->month==6 ||GPS->month==9 ||GPS->month==11 ){  

if(GPS->day>30){          /*上述幾個(gè)月份是30天每月,2月份還不足30*/  

GPS->day=1;  

GPS->month++;  

}  

}  

else{  

if(GPS->day>31){          /*剩下的幾個(gè)月份都是31天每月 */

GPS->day=1;  

GPS->month++;  

}  

}  

if(GPS->year % 4 == 0 ){  

if(GPS->day > 29 && GPS->month ==2){       /*閏年的二月是29天*/  

GPS->day=1;  

GPS->month++;  

}  

}  

else{  

if(GPS->day>28 &&GPS->month ==2){      /*其他的二月是28天每月*/  

GPS->day=1;  

GPS->month++;  

}  

}  

if(GPS->month>12){  

GPS->month-=12;  

GPS->year++;  

}         

}  

}


void gps_parse(char *line,GPS_INFO *GPS)  

{  

    int tmp;  

    char c;  

    char* buf=line;  

    c=buf[5];  

  

    if(c=='C')/* "GPRMC" */ 

    {

GPS->D.hour   =(buf[7]-'0')*10+(buf[8]-'0');  

GPS->D.minute =(buf[9]-'0')*10+(buf[10]-'0');  

GPS->D.second =(buf[11]-'0')*10+(buf[12]-'0');  

tmp = GetComma(9,buf);      /*得到第9個(gè)逗號(hào)的下一字符序號(hào)*/  

GPS->D.day    =(buf[tmp+0]-'0')*10+(buf[tmp+1]-'0');  

GPS->D.month  =(buf[tmp+2]-'0')*10+(buf[tmp+3]-'0');  

GPS->D.year   =(buf[tmp+4]-'0')*10+(buf[tmp+5]-'0')+2000;  

/*********************************************************/  

GPS->status   =buf[GetComma(2,buf)];     /*狀態(tài)*/  

GPS->latitude =get_double_number(&buf[GetComma(3,buf)]); /*緯度*/  

GPS->NS       =buf[GetComma(4,buf)];             /*南北緯 */ 

GPS->longitude=get_double_number(&buf[GetComma(5,buf)]); /*經(jīng)度*/  

GPS->EW       =buf[GetComma(6,buf)];             /*東西經(jīng) */ 

UTC2BTC(&GPS->D);                        /*轉(zhuǎn)北京時(shí)間*/  

    }  

    if(c=='A') /*"$GPGGA" */

    {

GPS->high =get_double_number(&buf[GetComma(9,buf)]); 

GPS->num =get_int_number(&buf[GetComma(7,buf)]); 

    }  

}  


voidshow_gps(GPS_INFO *GPS)

{  

     printf("年份     : %ld-%02d-%02d\n",GPS->D.year,GPS->D.month,GPS->D.day);

     printf("時(shí)間     : %02d:%02d:%02d\n",GPS->D.hour,GPS->D.minute,GPS->D.second);

     printf("緯度     : %s %10.4f\n",(GPS->NS=='N')?"北緯":"南緯",GPS->latitude);

     printf("經(jīng)度     : %s %10.4f\n",(GPS->EW=='W')?"西經(jīng)":"東經(jīng)",GPS->longitude);

     printf("衛(wèi)星數(shù)   : %02d\n",GPS->num);

     printf("高度     : %.4f\n",GPS->high);

     printf("狀態(tài)     : %s\n",(GPS->status=='A')?"定位":"導(dǎo)航");

     printf("--------------------\n");  

}


int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)  

{  

    struct termios newtio,oldtio;  

    if  ( tcgetattr( fd,&oldtio)  !=  0) {   

        perror("SetupSerial 1");  

        return -1;  

    }  

    bzero( &newtio, sizeof( newtio ) );  

    newtio.c_cflag  |=  CLOCAL | CREAD;  

    newtio.c_cflag &= ~CSIZE;  

  

    switch( nBits )  

    {  

    case 7:  

        newtio.c_cflag |= CS7;  

        break;  

    case 8:  

        newtio.c_cflag |= CS8;  

        break;  

    }  

  

    switch( nEvent )  

    {  

   case 'o': 

     case 'O':  

       newtio.c_cflag |= PARENB;  

       newtio.c_cflag |= PARODD;  

       newtio.c_iflag |= (INPCK | ISTRIP);  

        break;  

   case 'e':   

   case 'E': 

       newtio.c_iflag |= (INPCK | ISTRIP);  

       newtio.c_cflag |= PARENB;  

       newtio.c_cflag &= ~PARODD;  

       break;  

   case 'n':    

   case 'N': 

       newtio.c_cflag &= ~PARENB;  

       break;  

   case 's': 

   case 'S':  

       newtio.c_cflag &= ~PARENB;

       newtio.c_cflag &= ~CSTOPB;

       break;

   default:

       printf("Unsupported parity\n"); 

   return -1; 

    }  

  

    switch( nSpeed )  

    {  

    case 2400:  

        cfsetispeed(&newtio, B2400);  

        cfsetospeed(&newtio, B2400);  

        break;  

    case 4800:  

        cfsetispeed(&newtio, B4800);  

        cfsetospeed(&newtio, B4800);  

        break;  

    case 9600:  

        cfsetispeed(&newtio, B9600);  

        cfsetospeed(&newtio, B9600);  

        break;  

    case 115200:  

        cfsetispeed(&newtio, B115200);  

        cfsetospeed(&newtio, B115200);  

        break;  

    case 460800:  

        cfsetispeed(&newtio, B460800);  

        cfsetospeed(&newtio, B460800);  

        break;  

default:  

cfsetispeed(&newtio, B9600);  

cfsetospeed(&newtio, B9600);  

break;  

}  

    if( nStop == 1 )  

    newtio.c_cflag &=  ~CSTOPB;  

    else if ( nStop == 2 )  

    newtio.c_cflag |=  CSTOPB;  

    newtio.c_cc[VTIME]  = 0;/*超時(shí) 重要*/  

    newtio.c_cc[VMIN] = 100;/*返回的最小值  重要*/  

    tcflush(fd,TCIFLUSH);  

    if((tcsetattr(fd,TCSANOW,&newtio))!=0)  

    {  

        perror("com set error");  

        return -1;  

    }  

    return 0;  

}  


int Get_GPSData(char* gpd,char* buf,char* tar_value)

{

char *pos = NULL;

int cur = 0,counter=1,i =0; 

pos = strstr(buf,gpd);  

if(pos == NULL){   

return counter;

}

cur = pos - buf;

tar_value[0]='$';

for(i = cur; i < BUFLEN; i++){    

  if(buf[i]!='$' && buf[i]!='\n' ){ 

tar_value[counter]=buf[i];

counter++;

  } else{

tar_value[counter]='\0';

break;

}

}

return counter;

}


int main(void)  

{  

    GPS_INFO GPS;

    int fd1,nset1,nread;  

    char buf[BUFLEN],tar_value[512];  


    fd1 = open(TTYUSB, O_RDWR);/*打開串口*/  

    if (fd1 == -1)  

    exit(1);  

  

    nset1 = set_opt(fd1,BAUD_RATE, DATA_BITS, NEVENT, NSTOP);/*設(shè)置串口屬性*/  

    if (nset1 == -1)  

    exit(1);  

  

    while(1)  

    {  

        memset(buf,0,BUFLEN); 

memset(tar_value,0,sizeof(tar_value));

        nread = read(fd1, buf, BUFLEN);/*讀串口*/  

        if (nread > 0){  

if(Get_GPSData("GPGGA",buf,tar_value) <70){

sleep(2);

                continue;

            } 

            gps_parse(tar_value,&GPS);

memset(tar_value,0,sizeof(tar_value));

if(Get_GPSData("GPRMC",buf,tar_value) <70){

sleep(2);

                continue;

            } 

            gps_parse(tar_value,&GPS);

            show_gps(&GPS);

        }  

        sleep(2);/*睡眠,等待數(shù)據(jù)多一點(diǎn) */ 

    }  

    close(fd1);  

    return 0;  

}

執(zhí)行結(jié)果如下:
年份     : 2014-07-20
時(shí)間     : 10:16:20
緯度     :  北緯 3913.6049
經(jīng)度     :  東經(jīng) 10154.0622
衛(wèi)星數(shù)   : 05
高度      : 449.3000
狀態(tài)      : 定位

參考文:http://www.cnblogs.com/tianciliangen/p/3796701.html ,http://blog.csdn.net/zhandoushi1982/article/details/7947682


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI