一份相对较完整的协议文本,并且编写了一个相对较完善的 GPS 协议解析程序。
上图是我所说的测试程序,已经可以获得定位数据及相关卫星信息。
NMEA 0183 是美国国家海洋电子协会(National Marine Electronics Association ) 为海用电子设备制定的标准格式。目前业已成了 GPS 导航设备统一的 RTCM 标准协议。
序号 | 命令 | 说明 | 最大帧长 |
1 | $GPGGA | 全球定位数据 | 72 |
2 | $GPGSA | 卫星PRN 数据 | 65 |
3 | $GPGSV | 卫星状态信息 | 210 |
4 | $GPRMC | 运输定位数据 | 70 |
5 | $GPVTG | 地面速度信息 | 34 |
6 | $GPGLL | 大地坐标信息 |
|
7 | $GPZDA | UTC 时间和日期 |
|
注:发送次序$PZDA 、$GPGGA 、$GPGLL 、$GPVTG 、$GPGSA 、$GPGSV*3 、$GPRMC
协议帧总说明:
该协议采用ASCII 码,其串行通信默认参数为:波特率=4800bps ,数据位=8bit ,开始位=1bit ,停止位=1bit ,无奇偶校验。
帧格式形如:$aaccc,ddd,ddd,…,ddd*hh<CR><LF>
1 、“$”-- 帧命令起始位
2 、aaccc-- 地址域,前两位为识别符,后三位为语句名
3 、ddd…ddd— 数据
4 、“* ”— 校验和前缀
5 、hh— 校验和, $ 与* 之间所有字符代码的校验和(各字节做异或运算,得到校验和后,再转换16 进制格式的ASCII 字符。)
6 、 <CR><LF>-- 帧结束,回车和换行
其中 $GPRMC 比较重要,下面略加介绍。
1 、$GPRMC( Recommended Minimum Specific GPS/TRANSIT Data)
帧头 | UTC 时间 | 状态 | 纬度 | 北纬/ 南纬 | 经度 | 东经/ 西经 | 速度 |
$GPRMC | hhmmss.sss | A/V | ddmm.mmmm | N/S | dddmm.mmmm | E/W | 节 |
方位角 | UTC 日期 | 磁偏角 | 磁偏角方向 | 模式 | 校验 | 回车换行 |
度 | ddmmyy | 000 - 180 | E/W | A/D/E/N | *hh | CR+LF |
格 式: $GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh<CR><LF>
$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 ( 一节也是 1.852 千米/小时)
字段 8 :方位角,度( 二维方向指向,相当于二维罗盘)
字段 9 :UTC 日期,DDMMYY 格式
字段10 :磁偏角,(000 - 180 )度(前导位数不足则补0 )
字段11 :磁偏角方向,E= 东,W= 西
字段12 :模式,A= 自动,D= 差分,E= 估测,N= 数据无效(3.0 协议内容)
字段13 :校验值
对应的程序代码如下:
- //运输定位数据
- private bool GPRMC_Parse( string data)
- {
- string [] source = Split(data, "$GPRMC" );
- if (source != null && source.Length >= 12)
- {
- //状态
- this .AnchorState = source[2];
- //纬度
- if (source[4].Length > 0 && source[3].Length > 2)
- {
- this .Latitude = string .Format( "{0}{1},{2}" , source[4], source[3].Substring(0, 2), source[3].Substring(2));
- }
- else
- {
- this .Latitude = "" ;
- }
- //经度
- if (source[6].Length > 0 && source[5].Length > 3)
- {
- this .Longitude = string .Format( "{0}{1},{2}" , source[6], source[5].Substring(0, 3), source[5].Substring(3));
- }
- else
- {
- this .Longitude = "" ;
- }
- //速度
- if (source[7].Length > 0)
- {
- this .NSpeed = double .Parse(source[7]);
- }
- else
- {
- this .NSpeed = 0;
- }
- //方位
- if (source[8].Length > 0)
- {
- this .Track = double .Parse(source[8]);
- }
- else
- {
- this .Track = 0;
- }
- //磁偏角和方位
- if (source[10].Length > 0 && source[11].Length > 0)
- {
- this .Magnetic = string .Format( "{0} {1}" , source[11], source[10]);
- }
- else
- {
- this .Magnetic = "" ;
- }
- //模式
- if (source.Length >= 13)
- {
- this .WorkMode = source[12];
- }
- //时间
- try
- {
- if (source[9].Length == 6 && source[1].Length >= 6)
- {
- string dtString = string .Format( "{0}-{1}-{2} {3}:{4}:{5}" ,
- source[9].Substring(4),
- source[9].Substring(2, 2),
- source[9].Substring(0, 2),
- source[1].Substring(0, 2),
- source[1].Substring(2, 2),
- source[1].Substring(4));
- this .UTCDateTime = DateTime.Parse(dtString);
- }
- }
- catch { return false ; }
- return true ;
- }
- return false ;
- }