全球时区的划分:

  每个时区跨15°经度。以0°经线为界向东向西各划出7.5°经度,作为0时区。即0时区的经度范围是7.5°W——7.5°E。从7.5°E与7.5°W分别向东、向西每15°经度划分为一个时区,直到东11区和西11区。东11区最东部的经度是172.5°E,由172.5°E——180°之间就是东12区。西11区最西部的经度是172.5°W,由172.5°W——180°之间就是西12区。东、西12区各占经度7.5°,合成一个完整的时区,即全球总共划分为24个时区。东、西12区钟点相同,日期相差1天,因此180°称为理论上的国际日期变更线。
  由于地球的自转运动,不同地区有不同的地方时间,为了解决时间混乱的问题,采取了划分时区的办法。每个时区中央经线所在地的地方时间就是这个时区共用的时间,称为区时。在实际应用中各国不完全按照区时来定时间,许多国家制定一个法定时,作为该国统一使用的时间,例如我国使用120°E的地方时间,称为北京时间。

  GPS 上电后,每隔一定的时间就会返回一定格式的数据,数据格式为:
$信息类型,x,x,x,x,x,x,x,x,x,x,x,x,x每行开头的字符都是'$',接着是信息类型,后面是数据,以逗号分隔开。
一行完整的数据如下:
$GPRMC,080655.00,A,4546.40891,N,12639.65641,E,1.045,328.42,170809,,,A*60

GPS信息类型:

GPGSV:可见卫星信息
GPGLL:地理定位信息
GPRMC:推荐最小定位信息
GPVTG:地面速度信息
GPGGA:GPS定位信息
GPGSA:当前卫星信息
GPRMC 最小定位信息:

数据详解:$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh
  <1> UTC 时间,hhmmss(时分秒)格式
  <2> 定位状态,A=有效定位,V=无效定位
  <3>纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
  <4> 纬度半球N(北半球)或S(南半球)
  <5>经度dddmm.mmmm(度分)格式(前面的0也将被传输)
  <6> 经度半球E(东经)或W(西经)
  <7>地面速率(000.0~999.9节,前面的0也将被传输)
  <8>地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输)
  <9> UTC 日期,ddmmyy(日月年)格式
  <10>磁偏角(000.0~180.0度,前面的0也将被传输)
  <11> 磁偏角方向,E(东)或W(西)
  <12>模式指示(仅NMEA01833.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)

解析内容:

1.时间,这个是格林威治时间,是世界时间(UTC),我们需要把它转换成北京时间(BTC),BTC和UTC差了8个小时,要在这个时间基础上加8个小时。
2. 定位状态,在接收到有效数据前,这个位是‘V’,后面的数据都为空,接到有效数据后,这个位是‘A’,后面才开始有数据。
3. 纬度,我们需要把它转换成度分秒的格式,计算方法:如接收到的纬度是:4546.40891
  4546.40891/100=45.4640891可以直接读出45度, 4546.40891–45*100=46.40891, 可以直接读出46分
  46.40891–46 =0.40891*60=24.5346读出24秒, 所以纬度是:45度46分24秒。
4. 南北纬,这个位有两种值‘N’(北纬)和‘S’(南纬)
5. 经度的计算方法和纬度的计算方法一样
6. 东西经,这个位有两种值‘E’(东经)和‘W’(西经)
7.速率,这个速率值是海里/时,单位是节,要把它转换成千米/时,根据:1海里=1.85公里,把得到的速率乘以1.85。
8. 航向,指的是偏离正北的角度
9. 日期,这个日期是准确的,不需要转换

GPGGA GPS定位数据

数据详解:$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*xx<CR><LF>
$GPGGA:起始引导符及语句格式说明(本句为GPS定位数据);
  <1> UTC 时间,格式为hhmmss.sss;
  <2> 纬度,格式为ddmm.mmmm(第一位是零也将传送);
  <3> 纬度半球,N 或S(北纬或南纬)
  <4> 经度,格式为dddmm.mmmm(第一位零也将传送);
  <5> 经度半球,E 或W(东经或西经)
  <6> 定位质量指示,0=定位无效,1=定位有效;
  <7>使用卫星数量,从00到12(第一个零也将传送)
  <8>水平精确度,0.5到99.9
  <9>天线离海平面的高度,-9999.9到9999.9米M指单位米
  <10>大地水准面高度,-9999.9到9999.9米M指单位米
  <11>差分GPS数据期限(RTCMSC-104),最后设立RTCM传送的秒数量
  <12>差分参考基站标号,从0000到1023(首位0也将传送)。

解析内容:

  第9,10 个字段,海平面高度和大地水准面高度,单位是米

GPVTG 地面速度信息   

$GPVTG,<1>,T,<2>,M,<3>,N,<4>,K,<5>*hh
  <1> 以正北为参考基准的地面航向(000~359度,前面的0也将被传输)
  <2> 以磁北为参考基准的地面航向(000~359度,前面的0也将被传输)
  <3> 地面速率(000.0~999.9节,前面的0也将被传输)
  <4> 地面速率(0000.0~1851.8公里/小时,前面的0也将被传输)
  <5> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效

GPGSV 可视卫星状态

  例:$GPGSV,2,1,08,06,33,240,45,10,36,074,47,16,21,078,44,17,36,313,42*78
  标准格式: $GPGSV,(1),(2),(3),(4),(5),(6),(7),…(4),(5),(6),(7)*hh(CR)(LF) 
各部分含义为:
  (1)总的GSV语句电文数;2;
  (2)当前GSV语句号:1;
  (3)可视卫星总数:08;
  (4)PRN码(伪随机噪声码) 也可以认为是卫星编号
  (5)仰角(00~90度):33度;
  (6)方位角(000~359度):240度;
  (7)信噪比(00~99dB):45dB(后面依次为第10,16,17号卫星的信息);   *总和校验域;    hh 总和校验数:78;   (CR)(LF)回车,换行。   
注:每条语句最多包括四颗卫星的信息,每颗卫星的信息有四个数据项,即:
    (4)-卫星号,(5)-仰角,(6)-方位角,(7)-信噪比。   
例:
  $GPGSV,3,1,10,24,82,023,40,05,62,285,32,01,62,123,00,17,59,229,28*70
  每条语句包含四部分内容,例如:第一部分是“24,82,023,40”,第二部分是“05,62,285,32”等等。
每部分的第一个词为PRC,第二个词为卫星高程,跟着为方位角和信号强度。
  这个语句里最重要的指标应该算是“信号躁声比(signal-to-noise ratio)”(以下简称为SNR)。
这个数值标示卫星信号的接收率。我们知道,卫星是以相同的强度发射信号,但是传播过程中难免会遇到诸如树和墙之类的 障碍物,这样就影响了信号的识别。
典型的SNR值在0到50之间,其中50表示非常好的信号。(SNR可以达到99)。

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:校验值

以MTK平台主机获取到的数据为例:

$GPRMC,092927.000,A,2235.9058,N,11400.0518,E,0.000,74.11,151216,,D*49
$GPVTG,74.11,T,,M,0.000,N,0.000,K,D*0B
$GPGGA,092927.000,2235.9058,N,11400.0518,E,2,9,1.03,53.1,M,-2.4,M,0.0,0*6B
$GPGSA,A,3,29,18,12,25,10,193,32,14,31,,,,1.34,1.03,0.85*31
$GPGSV,3,1,12,10,77,192,17,25,59,077,42,32,51,359,39,193,49,157,36*48
$GPGSV,3,2,12,31,47,274,25,50,46,122,37,18,45,158,37,14,36,326,18*70
$GPGSV,3,3,12,12,24,045,45,26,17,200,18,29,07,128,38,21,02,174,*79
1
2
3
4
5
6
7
GPRMC的信息以上格式可以解析为:

09h29m27s,有效定位,维度2235.9058(海里/时,单位是节),北半球,经度11400.0518,东经,地面速率0.000,地面航向74.11(偏离正北的角度),UTC日期15日12月16年,磁偏角,磁偏角方向,

GPS的数据解析

需要定义重要的结构体来表示时间和GPS信息

typedef struct{
  int year;
  int month;
  int day;
  int hour;
  int minute;
  int second;
}date_time;

typedef struct{
  date_time D; //时间
  char status; //接收状态
  double latitude; //纬度
  double longitude; //经度
  char NS; //南北半球
  char EW; //东西半球
  double speed; //速度
  double high; //海拔高度
}GPS_INFO;

//得到指定序号的逗号位置
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;
}
return 0;
}

static double get_double_number(char *s) //将数据转化为double类型的数据
{
char buf[128];
int i;
double rev;
i=GetComma(1,s);
strncpy(buf,s,i);
buf[i]=0;
rev=atof(buf);

return rev;

}
static void UTC2BTC(date_time *GPS) //将UTC时间转化为北京时间
{

GPS->second++;
if(GPS->second>59){
GPS->second=0;
GPS->minute++;
if(GPS->minute>59){
GPS->minute=0;
GPS->hour++;
}
}

GPS->hour+=8;
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){
GPS->day=1;
GPS->month++;
}
}
else{
if(GPS->day>31){
GPS->day=1;
GPS->month++;
}
}
if(GPS->year % 4 == 0 ){
if(GPS->day > 29 && GPS->month ==2){
GPS->day=1;
GPS->month++;
}
}
else{
if(GPS->day>28 &&GPS->month ==2){
GPS->day=1;
GPS->month++;
}
}
if(GPS->month>12){
GPS->month-=12;
GPS->year++;
}
}
}
unsigned char Data_CalcFCS(char *msg_ptr, unsigned char len)
{
unsigned char x;
unsigned char xorResult;

xorResult = 0;

for ( x = 0; x < len; x++, msg_ptr++ )
xorResult = xorResult ^ *msg_ptr;

return ( xorResult );
}

void gps_parse(char *line,GPS_INFO *GPS) //解析GPRMC格式的数据
{
int tmp;
unsigned char status, fcs = 0;
char *ptr = NULL;
char *buf=line;

if(strncmp(buf+3,"RMC",3)==0||strncmp(buf+3,"GGA",3)==0)
{

//printf("GPRMC founded!\n");
if(strncmp(buf+3,"RMC",3)==0)
{
status =buf[GetComma(2,buf)];
if(status == 'A')
{
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);
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)];
GPS->latitude =get_double_number(&buf[GetComma(3,buf)]);
GPS->NS =buf[GetComma(4,buf)];
GPS->longitude=get_double_number(&buf[GetComma(5,buf)]);
GPS->EW =buf[GetComma(6,buf)];
}
}

if(strncmp(buf+3,"GGA",3)==0)
{
ptr = strchr(buf,'*');
if(ptr!=NULL){
fcs = strtoul(ptr + 1,NULL,16);
if(fcs == Data_CalcFCS(buf+1,(unsigned char)(ptr-buf-1)))
{
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');

GPS->latitude =get_double_number(&buf[GetComma(2,buf)]);
GPS->NS =buf[GetComma(3,buf)];
GPS->longitude=get_double_number(&buf[GetComma(4,buf)]);
GPS->EW =buf[GetComma(5,buf)];
GPS->high = get_double_number(&buf[GetComma(9,buf)]);
}
}
}
#ifdef USE_BEIJING_TIMEZONE
UTC2BTC(&GPS->D);
#endif
}
}

最新文章

  1. [LeetCode] Tenth Line 第十行
  2. [转]CSS 类名的单词连字符:下划线还是横杠?
  3. Navicat Premium下sql导入中文乱码解决方案
  4. BootStrap 模态框基本用法
  5. 30、准确计算CoreText高度的方法
  6. asp.net 发布后用IP访问正常,用机器名访问布局出错
  7. 数据加工处理拼sql
  8. JavaEE的13种核心技术
  9. ●POJ 2284 That Nice Euler Circuit
  10. foaf
  11. linux php7.2安装扩展memcached
  12. docker 私有 repository
  13. 【Luogu4921】情侣?给我烧了!(组合计数)
  14. Top sort 双队列
  15. TP微信扫码支付
  16. 深入理解ajax系列第二篇——请求方式
  17. HDU 2492 Ping pong (数状数组)
  18. SpringBoot创建多模块方式以及打包方式
  19. 关于485通信不稳定问题解决方案[STM32产品问题]
  20. allocator类

热门文章

  1. 查看Oracle数据库中的执行计划
  2. 前后端分离项目中后台集成shiro需要注意的二三事
  3. ubuntu安装和使用git
  4. 操作excel--xlwt/xlrd/xlutils模块
  5. ecshop后台增加模块菜单详细教程
  6. idea下载和设置自动翻译(有道)
  7. Nacos1.1.3小试牛刀
  8. ngnix高并发的原理实现(转)
  9. JVM可视化监控工具jconsole以及jvisualvm的配置
  10. 并发问题java