您好,登錄后才能下訂單哦!
一、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ì)分析:
(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ì)分析:
(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ì)分析:
(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ǔ)句):
(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ì)分析:
(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ù)解析
/*********************************************************************************/
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
免責(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)容。