房兰刚
【摘要】本论文介绍了遵循NMEA0183协议的GPS定位的数据格式,提出了利用API函数进行GPS串口通讯的方法,设计了具体的软件设计和实现。运行结果表明,所设计的系统运行稳定、定位准确、实时性强。为进一步进行车辆的导航定位提供了保障。
【关键词】VC++6.0;GPS;NMEA0183协议;串口通信
一、前言
GPS是20世纪70年代由美国陆海空三军联合研制的新一代空间卫星导航定位系统。为了实现GPS数据采集、接收与处理以及计算机与GPS接收机的串口通信,计算机的串行端口就为计算机和GPS 接收机提供了数据传输通道。Visual C++是一种可视化的语言,还提供ODBC类[2]。本系统的数据采集主要遵循NMEA0183协议,对之进行处理后,通过ODBC接口将用户位置、时间、速度和航向等信息保存到用户建立的数据库中,为数据处理提供定位信息。
二、GPS定位的数据格式――NMEA0183数据格式
NMEA0183协议是美国国家海洋电子协会(National Marine Electronics Association)制定的GPS接口协议标准[3]。在串口通讯模块中,系统采用的GPS数据格式是RMC数据格式,通过判断信号状态来确认是否为有效信号。采集的数据包括经度、纬度、时间、状态、航向角、速度等。
本文采用的是GPRMC定位语句,采集程序忽略其余的信息,GPRMC定位语句结构如下:
$GPRMC,HHMMSS,A,AAAA.AAAA,N,LLLLL.LLLL,E,VVV.V,DDD.D,DDMMYY,MMM.M,W,A,..SS,CRLF
以下面的语句为例进行说明语句的含义:
$GPRMC,013946.00,A,3202.1855,N,11849.0769,E,0.05,218.30,111106, 013.5,W,A*20..
在此列中各數据段通过逗号分开,其中:
◇“$GPRMC”为帧头,表示这条语句为RMC格式语句
◇01 UTC时间,hhmmss.sss(时分秒.毫秒)格式。UTC时间为GPS系统所采用的时间系统,以原子时(ATI-Atomic Time International)的秒长作为时间单位,时间起算原点UTC零时定义在1980年1月6日子夜零点。示例中时间01时39分46.00秒。
◇02 定位状态,A=有效定位,V=无效定位 。
◇03 纬度:格式为“ddmm.Mmmm”;示例中为“北纬(N)32度02.1855分”。
◇04 经度:格式为“dddmm.Mmmm”;示例为“东经(E)118度49.0769分”。
◇05 相对位移速度:0.05 knots。
◇06 表示方位角,即相对位移方向:从000.0°~359.9°示例为“218.30度”。
◇07 日期:111106为UTC标准日期,格式为“mm/dd/yy”11日11月06年
◇08 013.5——磁偏移量值。表示磁极变量值为13.5,单位是度。
◇09 W表示地磁变化方向,包括w或E。
◇10 E*6E——校验码,用来验证语句中数据的完整性。
在这些数据中,本研究主要关心的是地理坐标和时间,即纬度、经度、定位状态和UTC日期、时间信息。
三、GPS的串口通信的软件设计
串口通信的软件设计主要是针对GPS数据的实时接收、存储和坐标转换,使其融为一体。其中主要用到了GPS串口的开发、数据库处理以及坐标转换的相关编程。
根据GPS模块数据传输机制,必须给串口设置如下的参数:数据传输率9600bit/s,数据位8bit,停止位1bit,无奇偶校验位,可以根据需要选择不同的COM口。针对有些计算机上没有留有COM口,也可以使用USB转COM口工具,直接使用计算机上的USB接口。GPS信号输出时间间隔通常在0~2s范围内,在实时性跟踪时,采用每隔1s采样一次。本程序中每1s更新一次经度、纬度、时间、速度和航向等数据。
在本系统中,串口通讯技术采用API(Appli-
cation Programming Interface)函数的方法,通过设置CSerialPortEx类为串口通信支持类和CConfigDlg类为串口参数配置类,先对串行口通信参数进行选择;然后在串口数据到达时,CSerialPortEx类将数据发送到程序主窗口;控制模块每隔一段时间察看一次主窗口串口数据接收缓冲区,并对符合要求的数据进行处理后保存在一个数据文件中以供后续处理使用,同时请求显示模块更新数据。
其具体操作步骤如下:
1.添加SerialPort.h和SerialPort.cpp两文件到本程序中。创建串口参数配置类CConfigDlg。
2.将这两类的头文件名添加到主程序中。定义CSerialPortEx类的变量m_Port;通过设定定时器OnTimer函数来响应ON(开始接收)和OFF(停止接收)按钮。程序如下:
void CGPSView::OnReceiveStart()//开始接收
{
m_Port.StartMonitoring();//打开线程,开始接收串口数据
m_nTimer=SetTimer(1,1000,0);//启动定时接收器,每隔1s接收一次
}
void CGPSView::OnReceiveStop()//停止接收
{
m_Port.StopMonitoring();//关闭线程,停止接收串口数据
KillTimer(1);//关闭定时接收器
}
3.采用查询方式:设置一个定时器,每隔一段时间察看一次串口数据接收缓冲区,在定时器OnTimer函数中确定数据的提取方法。通过查找上一个GPS语句结束标志LF和下一个CR结束标志之间的一句GPS语句。依次按照GPGGA输出数据格式查找获取数据,并分别给对话框中的变量中。如下所示:
void CGPSView::OnTimer(UINT nIDEvent)
{
if(nIDEvent!=1)
return;//若不是GPS定时处理事件,则返回
while((m_strReceived.Find(0x0d)!=-1)&&(m_strReceived.Find(0x0a)!=-1))
//循环读取GPGGA定位语句
{
int startLF=m_strReceived.Find(0x0a);
//startLF:缓冲区中第一个GPS语句结束标志LF的位置,即下一GPS语句开始标志
int endCR=m_strReceived.Find(0x0d);
//endCR:缓冲区中第一个GPS语句结束标志CR的位置。
//若endCR在startLF之前,则两个结束标志属于同一GPS语句,需继续搜索下一个LF标志
if(startLF>endCR)
endCR=m_strReceived.Find(0x0d,startLF);
//复制这一句GPS语句,并从接收缓冲区中删除从上一句结束标志LF到本句结束标志CR间的数据
CString msg=m_strReceived.Mid(startLF+1,
endCR-startLF-1);
m_strReceived.Delete(0,endCR+1);
//判断是否GPGGA定位语句,若不是则跳过后续循环,继续处理下一句,否则删除“$GPGGA”,继续处理该句的其它部分。
if(msg.Left(6).Compare("$GPGGA")!=0)
continue;
msg.Delete(0,msg.Find(',')+1);
…………………………………………
}
}
运行结果如图1所示,分别获取了经度、纬度、速度、航向、海拔高度等数值。
四、结束语
利用面向对象的可视化语言VC++6.0封装的API函数实现了计算机和GPS的串口通信,包括GPS串口的开发、数据库处理以及坐标转换。实验通过把GPS 接收机和电脑的串口相连,快速获取了GPS 定位导航信息,运行结果证明系统运行稳定、定位精度高、定位误差小,实时性强,为进一步研究GPS的定位导航提供了理论依据。
参考文献
[1]罗鸣,曹冲,肖雄兵等.全球定位系统[M].北京:電子工业出版社,2008.
[2]Davis Chapman驮长乐译.学用Visual C++6.0[M].北京清华大学出版社,2004.
[3]唐旭荣,唐斌,蒋德.卫星导航软件接收机原理与设计[M].北京:国防工业出版社,2008.
指导老师、通讯作者:吴延霞。