GPSGPZDA数据解析C语言.docx
《GPSGPZDA数据解析C语言.docx》由会员分享,可在线阅读,更多相关《GPSGPZDA数据解析C语言.docx(19页珍藏版)》请在冰豆网上搜索。
GPSGPZDA数据解析C语言
摘要
GPS(GlobalPositioningSystem)可说是目前最热门、最受人瞩目的一项科技。
简单的说,GPS是利用位于地球同步轨道上的同步卫星,以其相对位置的关系,来测出精确的位置,事实上,接收机往往可以锁住4颗以上的卫星,这时,接收机可按卫星的星座分布分成若干组,每组4颗,然后通过算法挑选出误差最小的一组用作定位,从而提高精度。
GPS除了可作为精确的定位工具之外,同时也可以用作精密的测量工具。
在进行大范围、大面积的地面测量时,往往受限于地球本身的弧度与测量仪器的精密程度,甚至于当时的天候状况或测量人员本身的许多因素,导致测量的结果产生或多或少的误差。
倘若利用GPS来作为测量工具,由于人造卫星高悬于地表上空,受地表弯曲弧度的影响相对减少。
透过GPS与GIS的结合,更可以让我们更快速、精确地处理所需的资料。
发明准确的计时工具之后的短时间内,没有人会想象得到有了准确的时间会带来改变世界的冲击,影响了我们的生活,新兴的产品和服务产业都由其引发。
GPS对精确的位置就有如时钟对精确的时间一样,因此其得到大范围使用。
由于GPS定位需要非常精确的时间,每颗GPS卫星上都有精密的原子钟,所以发送的信号可以附带精确的时间信息。
对于接收机也就有一定要求,GPS卫星接收机种类很多,根据型号分为测地型、全站型、定时型、手持型、集成型;根据用途分为车载式、船载式、机载式、星载式、弹载式。
随着通信技术的迅速发展,为适应社会的需求,满足用户的需要,必须提高软件开发水平,近些年随着嵌入式操作系统的兴起,嵌入式终端与GPS的结合更加完善了GPS的可视性、功能性和操作性,使GPS的泛用性得到增强,用户的数量增多使功能需求越来越复杂,其中就有部分用户对时间精度要求较高,需要专门的语句格式来解析,这也是GPZDA得到应用并推广的原因之一。
无论是生活还是军事,GPS全球卫星定位系统都已经成为最重要的定位系统。
它的信号所包含的信息中有位置信号和时间信号,NMEA-0183协议的其他语句格式解析可以为用户指明自己的所处方位,时间信息却不是很准确。
用户所需要的除了准确的位置信息,还有收到信号时的准确时间。
GPZDA是NMEA0183协议中专门为解析时间准备的编码,比NMEA0183协议中的其他语句格式更加精确,因此其专用性受到用户认可。
经过20余年的实践证明,GPS系统是一个高精度、全天候和全球性的无线电导航、定位和定时的多功能系统。
GPS技术已经发展成为多领域、多模式、多用途、多机型的国际性高新技术产业。
关键字:
GPS0183协议GPZDA
图索引
前言
GPS全球卫星定位系统是目前世界上应用最广的定位系统,其准确性与可靠性都是首屈一指,由于GPS技术所具有的全天候、高精度和自动测量的特点,作为先进的测量手段和新的生产力,已经融入了国民经济建设、国防建设和社会发展的各个应用领域。
GPS的信号不仅能传输三维位置和三维速度,还能传输时间信号,它的卫星系统是在地面监测站的监控下进行工作的,卫星上的精密电子钟经常与监测站校时,以保证时间信号的准确。
因此,其时间信号也是GPS信号解析的一部分。
全球定位系统由三部分构成:
(1)地面控制部分,由主控站(负责管理、协调整个地面控制系统的工作)、地面天线(在主控站的控制下,向卫星注入寻电文)、监测站(数据自动收集中心)和通讯辅助系统(数据传输)组成;
(2)空间部分,由24颗卫星组成,分布在6个道平面上;(3)用户装置部分,主要由GPS接收机和卫星天线组成。
全球定位系统的主要用途:
(1)陆地应用,主要包括车辆导航、应急反应、大气物理观测、地球物理资源勘探、工程测量、变形监测、地壳运动监测、市政规划控制等;
(2)海洋应用,包括远洋船最佳航程航线测定、船只实时调度与导航、海洋救援、海洋探宝、水文地质测量以及海洋平台定位、海平面升降监测等;(3)航空航天应用,包括飞机导航、航空遥感姿态控制、低轨卫星定轨、导弹制导、航空救援和载人航天器防护探测等。
GPS的主要特点:
(1)全天候;
(2)全球覆盖;(3)三维定速定时高精度;(4)快速省时高效率;(5)应用广泛多功能。
NMEA-0183是美国国家海洋电子协会为海用电子设备制定的标准格式。
目前业已成了GPS导航设备统一的RTCM标准协议。
大多数常见的GPS接收机、GPS数据处理软件、导航软件都遵守或者至少兼容这个协议。
GPS接收机根据NMEA-0183协议的标准规范,将位置、速度等信息通过串口传送到PC机、PDA等设备。
NMEA通讯协议所规定的通讯语句都是以ASCII码为基础的,NMEA-0183协议语句的数据格式如下:
“$”为语句起始标志;“,”为域分隔符;“*”为校验和识别符,其后面的两位数为校验和,代表了“$”和“*”之间所有字符的按位异或值(不包括这两个字符);“/”为终止符,所有的语句必须以它来结束,也就是ASCII字符的“回车”(十六进制的0D)和“换行”(十六进制的0A)。
NMEA-0183协议包括GPGGA,GPRMC,GPGSA,GPGSV,GPZDA等语句格式,其中GPZDA的功能就是解析卫星信号中的时间信息,将其信号序列变为非专业人员可读取的文字。
通过这次课程设计我们可以了解,如何用GPZDA解析GPS的时间信号,在计算机上输出普通用户所能理解的语句,让用户能够在时间信息这方面更加精确地得到信息,给用户提供更可靠的更高水准的服务。
第一章GPS原理
GPS全球卫星定位系统由21颗工作卫星和3颗备用卫星组成。
它们分布在6个等间距的轨道平面上,每个轨道面上有4颗工作卫星。
GPS能覆盖全球,能够连续、实时、隐蔽地定位,一次定位时间仅几秒到十几秒,用户不发射任何电磁信号,只要接受卫星导航信号即可定位,所以可全天候昼夜作业。
GPS的卫星系统对于地面观测者来说,每天将提前4分钟见到同一颗GPS卫星位于地平线以上的卫星颗数随着时间和地点的不同而不同,最少可见到4颗,最多可见到11颗。
地面设备监控卫星上的各种设备是否工作正常,以及卫星是否一直沿着预定轨道运行。
除此之外,使用者接收机能够捕获到按一定卫星高度截止角所选择的待测卫星的信号,并跟踪这些卫星的运行,对所接收到的GPS信号进行变换、放大和处理,以便测量出GPS信号从卫星到接收机天线的传播时间,解译出GPS卫星所发送的导航电文,实时地
图1GPS卫星环绕图
计算出测站的三维位置,三维速度和时间。
GPS通过掌握卫星的位置,测定所在地点与卫星之间的距离,运用数学计算测得测站的三维位置,另外,接收机往往可以锁住4颗以上的卫星,收到四颗则加上高程值这时,接收机可按卫星的星座分布分成若干组,每组4颗,然后通过算法挑选出误差最小的一组用作定位,从而提高精度。
要了解卫星所处的准确位置,需要优化设计卫星运行轨道,并且,地面监测站要连续不断监测卫星的运行状态,适时发送控制指令,使卫星保持在正确的运行轨道。
每颗GPS卫星上都装置有十分精密的电子钟,并由监测站经常进行校准。
卫星除了发送定位导航信息,也能发送时间信息,GPS接收机收到信息后就能对时间进行校准。
所以,GPS接收机除了能准确定位之外,还可产生精确的时间信息。
第二章0183协议简介
NMEA—0183通信方式是由美国国家海洋电子协会开发、维护并发布的标准,目前大多数GPS接收设备都遵循这一标准,该接口协议定义了在波特率4800的串口数据总线上传输的电器信号需求、数据传输协议和时间以及详细的句型格式,以“句子”为单位进行发送。
假如数据域中的某个值无效,该值将被简单的忽略,但对应的“,”仍需发送。
图2NMEA-0183协议框架
图3编译过程流程图
2.1编译技术的简介
编译过程主要分为四个阶段,分别是词法分析、语法分析、语义分析和代码生成。
第一个阶段是词法分析,它是从左到右一个字符一个字符的读取源程序并对字符进行扫描和分解,从而识别一个一个单词。
第二个阶段是语法分析,它是在词法分析的基础上将一个一个的单词组成各类语法短语,如“程序”、“语句”、“表达式”等。
第三个阶段是语义分析,它的任务是审查源程序有无语义上的错误并且为代码收集类型信息。
最后一个阶段是代码生成,它是在语法分析和语义分析的基础上生成最终的目标程序。
2.2语法格式
NMEA0183的信息格式一般如下所示:
$aaaaa,df1,df2,....[CR][LF]
所有的信息由$开始,以换行结束,紧跟着$后的五个字符解释了信息的基本类型,多个参数之间用逗号隔开。
2.3协议类型
NMEA0183中有以下三种基本的协议类型:
2.3.1信息源
信息源的标准格式为:
$ttsss,df1,df2,....[CR][LF]
在紧随$后的两个字符是用来识别作为信息内容识别码的后面三个字符,信息识别码定义了保留的数据区,在NMEA0183的标准下,每个类型的数据区的信息内容是符合标准的。
例如:
$HCHDM,238,M[CR][LF]。
其中“HC”信息源是一个磁性的罗盘,“HDM”是表明后面的代表磁性的船首向航向,238是船首向航向的值,M则表示船首向航向值的磁性。
2.3.2查询
查询的标准格式为:
$ttllQ,sss,[CR][LF]
前面两个字符表示请求者的信息源的识别码,后面两个字符是被查询设备的识别码,最后一个字符说明这是一个查询的信息。
紧跟着的字符(SSS)包含了三个字的被查询内容的记忆信息。
例如:
$CCGPQ,ZDA[CR][LF]“CC”说明计算机正从“GP”这个设备查询ZDA中的内容。
GPS将会每隔1秒发送内容直到有新的请求。
2.3.3属性
这是一种使用没有在标准下预定义的特殊内容的方法。
它通常的格式为:
$PmmmA,df1,df2,....,[CR][LF]P说明是属性内容,mmm定义为厂商信息代码,A(A-Z)表明信息类型。
NMEA-0183协议定义的语句非常的多,主要有$GPGLL、$GPGGA、$GPVTG、$GPZDA等。
因为本次课题我们需要使用GPS-GPZDA进行数据解析所以我们只介绍GPZDA标准格式的样式。
2.4GPZDA语句格式
UTC时间/日期及本地时区偏移量
$GPZDA,<1>,<2>,<3>,<4>,*<5>[CR][LF]
<1>UTC时间,格式hhmmss.ss(前导位数不足则补0)。
<2>UTC日期,01到31(前导位数不足则补0)。
<3>UTC月份,01到12(前导位数不足则补0)。
<4>UTC年,格式yyyy。
<5>校验和。
第三章方案设计
编程的主要思想:
由于GPZDA的形式是:
$GPZDA,hhmmss,XX,XX,XXXX,,*hh,所以,我们学习老师的课件及上课的内容从而确定编程的主线:
通过对逗号的扫描来确定每一段的解析数据,需要进一步解析的就再次解析,从而最终解析出所有我们需要的数据。
具体的程序流程图如下,由主流程图和子流程图组成。
图4主流程图
对程序流程图的说明
主流程图:
通过对switch(n)语句中的n的值的输入选择:
n=0,打开文件a,并准备解析其中的数据;n=1,打开文件b,并准备解析其中的数据;n=2,手动输入数据,并准备对数据的解析。
若输入n为以上其它值,那么会出现报错并提示用户重新输入n的值。
其中打开文件部分,若失败则会显示NotOpen。
接着将数据放入到数组中然后进行解析,解析结果输出并保存到文件c中。
然后将数组中的数据全部清零,再次询问用户是否继续解析数据,若是则输入0,否就是输入0以外的其它的值,从而结束程序。
子流程图:
采用顺序结构,依次解析出,时分秒,年,月,日,最后将时分秒进一步解析,从而解析出最终单个的显示结果,最后输出的时候按照年月日时分秒的顺序显示即可。
注:
主子流程图均采用Visio软件绘制
图5解析子流程图
3.1总程序
#include
main()
{
FILE*fp;
charch[128]={'\0'};
charch1[10]={'\0'};
charchday[5]={'\0'};
charchmonth[5]={'\0'};
charchyear[5]={'\0'};
charchhour[5]={'\0'};
charchmin[5]={'\0'};
charchsec[8]={'\0'};
charchsum[10]={'\0'};
charafterch[128]={'\0'};
inti,j,n,m;/*定义并初始化一些数组,指针,整型变量等用于后续程序使用*/
printf("Thisprogramisfinishedbyourteam:
\nShenJianFengWangTingHeXiaoTian\nSongZhenZhongWuYunChaoCaiQiWei\n");
printf("FinishedTime:
2010-12-20\n\n");
HERE:
printf("Welcome!
Pleaseinputn(n=0or1or2)\n0meansOpentheFile'a.txt'\n1meansOpentheFile'b.txt'\n2meansManualOperationInput):
");
scanf("%d",&n);
while(n!
=0&&n!
=1&&n!
=2)
{printf("Error!
\nPlaeseinputnagain(n=0or1or2):
");
scanf("%d",&n);}
switch(n)
{
case(0):
printf("OpentheFile'a.txt'andanalysis:
");
if((fp=fopen("a.txt","r"))==NULL)
{
printf("Notopen\n");
exit(0);
}
fscanf(fp,"%s",&ch);
printf("%s\n",ch);
fclose(fp);/*打开文件a并读入需要解析的数据,并关闭文件*/
break;
case
(1):
printf("OpentheFile'b.txt'andanalysis:
");
if((fp=fopen("b.txt","r"))==NULL)
{
printf("Notopen\n");
exit(0);
}
fscanf(fp,"%s",&ch);
printf("%s\n",ch);
fclose(fp);/*打开文件b并读入需要解析的数据,并关闭文件*/
break;
case
(2):
printf("PleaseinputtheGPZDAdata(suchas:
$GPZDA,hhmmss,XX,XX,XXXX,,*hh):
");
scanf("%s",&ch);
break;
}/*switch选择语句用于实现a文件的打开,或b文件的打开,或手动输入的选择,不在选择范围内报错*/
for(i=0;i<128;i++)
{
afterch[i-1]=ch[i-1];
if(ch[i]!
=',');
else
break;
}/*解析$GPZDA*/
for(i=i+1,j=0;i<128;i++)/*j清0是为了再次的循环(第二次乱码的原因)*/
{
if(ch[i]!
=',')
{
ch1[j]=ch[i];
j++;
}
else
break;
}/*整体解析HHMMSS*/
for(i=i+1,j=0;i<128;i++)
{
if(ch[i]!
=',')
{
chday[j]=ch[i];
j++;
}
else
break;
}/*解析‘日’*/
for(i=i+1,j=0;i<128;i++)
{
if(ch[i]!
=',')
{
chmonth[j]=ch[i];
j++;
}
else
break;
}/*解析‘月’*/
for(i=i+1,j=0;i<128;i++)
{
if(ch[i]!
=',')
{
chyear[j]=ch[i];
j++;
}
else
break;
}/*解析‘年’*/
for(i=i+1,j=0;ch[i]!
='\0';i++)
{
if(ch[i]!
=','&&ch[i]!
='*')
{
chsum[j]=ch[i];
j++;
}
}/*解析‘校验和’*/
i=0;
for(j=0;j<2;j++,i++)
chhour[j]=ch1[i];
for(j=0;j<2;i++,j++)
chmin[j]=ch1[i];
for(j=0;j<5;i++,j++)
chsec[j]=ch1[i];/*进一步解析HHMMSS中的HH,MM,SS*/
fp=fopen("c.txt","a+");
fprintf(fp,"%s\r\n年%s\r\n月%s\r\n日%s\r\n时%s\r\n分%s\r\n秒%s\r\n校验和:
%s\r\n",afterch,chyear,chmonth,chday,chhour,chmin,chsec,chsum);
fclose(fp);/*将解析结果写入追加型文件c中,并输出*/
printf("%s\nyear:
%s\nmonth:
%s\nday:
%s\nhour:
%s\nmin:
%s\nsec:
%s\nJYH:
%s\n",afterch,chyear,chmonth,chday,chhour,chmin,chsec,chsum);/*WIN-TC界面显示输出*/
memset(ch,'\0',sizeof(ch));
memset(ch1,'\0',sizeof(ch1));
memset(chday,'\0',sizeof(chday));
memset(chmonth,'\0',sizeof(chmonth));
memset(chyear,'\0',sizeof(chyear));
memset(chhour,'\0',sizeof(chhour));
memset(chmin,'\0',sizeof(chmin));
memset(chsec,'\0',sizeof(chsec));
memset(chsum,'\0',sizeof(chsum));
memset(afterch,'\0',sizeof(afterch));/*清空所有的数组,以便再次解析不发生覆盖*/
printf("Doyouwanauseagain?
\nPleaseinput0(YES)orelse(NO):
");
scanf("%d",&m);
if(m==0)gotoHERE;
elseprintf("Thanksforyourusing,BYE!
");/*if语句用于判断是否需要再次的解析*/
getch();
}
3.2程序运行截图
图6程序运行截图1
上图所示为:
运行程序,出现如上图所示的指引界面,前段为我们团队的信息和完成时间,后段提示用户需要输入0,1,2其中之一来选择打开文件a,或打开文件b,或手动输入。
图7程序运行截图2
上图所示为:
用户在指引界面上输入0,就打开文件a,并解析其中的内容,并且在解析完后显示提示信息,再次输入0或其他来表征是继续还是结束程序。
图8程序运行截图3
上图所示为:
在选择是否继续的时候输入0,继续。
并再次输入1来表示打开文件b,并解析其中的数据,同样在解析完以后询问用户是否继续。
图9程序运行截图4
上图所示为:
在选择是否继续的时候输入0,继续。
并再次输入2来表示手动输入GPZDA解析数据,并解析,同样在解析完以后询问用户是否继续,用户按0以为的其他输入,结束程序。
图10程序运行截图5
设计中遇到的问题及解决方案
编程中的点滴总结:
问题:
1.文件打开失败:
由于文件的地址输入有误而导致的文件无法打开,最后修改了文件的地址,从而解决了打开失败的问题。
2.文件打开却无法读入数据:
由于使用了结构体函数fread,而此函数的使用格式及原则不是很熟悉,所以文件内的数据无法读入,最后改用fscanf函数,从而数据读入。
3.多次解析,后面解析的会覆盖前次解析的数据:
由于之前采用的文件写入类型是w型的,自然会出现覆盖现象,后改为a+的追加型,从而实现多次数据解析的保存到文件c中。
4.多次数据解析出现错误:
由于未加入清零程序,从而出现了后面的数据长度短于之前的长度而导致的后面解析的数据会残留前次的部分数据,后加入memset清零函数从而解决了该问题。
5.程序出现解析乱码:
由于j每次使用前未重新赋值为0,导致数据存储不是从数组的开始位置存储而产生一些乱码,后修改程序,j每次使用前均赋值为0,从而解决该问题。
优化:
1.基本功能实现以后优化一:
添加了欢迎界面以及一些指导用户使用的提示性语句,方便用户使用。
2.基本功能实现以后优化二:
在switch语句前添加了报错循环程序,使得用户输入n的值有误时,能报错并再次提示用户输入n(0,1,2之一)。
3.基本功能实现以后优化三:
添加了手动输入功能,运用了选择语句来实现并将手动的信息同步解析后信息输出,从而实现手动解析。
4.基本功能实现以后优化四:
添加了不同地址输入数据解析的程序,从而不需要通过改变程序中文件的地址来实现不同地址的文件打开的功能。
5.基本功能实现以后优化五:
在清零程序以后添加了循环语句,用以实现用户多次解析数据的实现。
收获:
1.编程从出现的问题,到解决问题后达到较满意的结果,其中都凝聚了我们全组人员的心血,一些编程的问题主要是由于c语言长时间不使用而导致一些指令语句的不熟悉以及格式的错误,而最后解决以后同时也加强了我们对于c语言的进一步了解和熟悉。
2.编程的优化过程中,我们在原有的基础程序上,添加了一些switch选择语句,goto循环语句等用于实现不同地址文件读入以及手动输入,一些优化的程序虽然不难,但还是需要我们去用语句去实现,依旧锻炼了我们的c语言功底。
心得体会
通过这次课程设计,加强了我们动手、思考和解决问题的能力。
在整个设计过程中,经常会遇到这样那样的情况,就是心里老想着这样的程序可以行得通,但实际编译运行,总是实现不了,因此耗费在这方面的时间很多。
做课程设计同时也是对课本知识的巩固和加强,由于课本上知识太多,平时课间的学习并不能很好地理解和运用各个程序的功能,所以在这次课程设计过程中,我们了解了很多语句的功能,进行了实践,并且对于其在编程中的使用有了更多的认识。
我们在设计期间结合相关资料,以分组的形式完成题目要求。
同学们能够实现程序的操作与演示,通过课程设计更深入地掌握了C语言的编程技巧,增强了动手能力,并锻炼了互相协作的精神。
每天的专注和辛劳,唤回了我们对通信课程与C语言的重新认识,对NMEA-0183的深刻理解,让我们实现了动手操作的目的。
在已度过的大学时间里我们大多数接触的是专业基础课。
我们在课堂上掌握的仅仅是专业基础课的理论面,如何去锻炼我们的实践面?
如何把我