1、基于 DSP的 GPRMC定位数据提取 目 录 一、绪论 . 2 二、 课设内容 . 3 2.1、 GPRMC 的基本原理 . 3 2.2、主要语句 . 5 2.3、串口调试的基本原理和过程 . 5 2.4、串口调试的主要程序语句 . 5 2.5、实验主程序 . 11 2.6、课设小结 . 15 三、参考文献 . 16 四、谢辞 . 17 一、绪论 本次课程设计就是 C语言编写一个级于 DSP 的 GPRMC 定位数据提取程序,然后进行调试和硬件仿真的过程。 要实现定位信息的提取和显示,首先要实现定位信息的传输,即通过相应的接口实现 GPS 接收机与 PC 机之间的通信。本次课设所实现的是,通
2、过天线接收GPS 卫星信号,并进行相应处理产生定位信息,再通过串口 (RS 232)输出。 GPS通讯协议较多,本课设采用应用最为广泛的 NMEA 0183 协议。在此协议中包括了 “$GPGGA” 、 “$GPGSA” 、 “$ GPGSV” 和 “$ GPRMC” 等格式,而我使用的是以最简格式 “$ GPRMC” 语句进行设计。 GPS( Global Positioning System)全球定位系统是利用美国的 24 颗 GPS地址卫星所发射的信号而建立的导航、定位、授时的系统。美国政府已承诺,在今后相当长的一段时间内, GPS 系统将向全世界免费开放。目前, GPS 系统广泛地应用
3、在导航、大地测量、精确授时、车辆定位及防盗等领域。从九十年代我国引进 GPS 定位技术开始,经过十多 年的市场培育, GPS 定位应用进入了发展的最好时机,未来十年基于 GPS 的应用将会改变我们的生活和工作方式。 目前市场上的大部分 GPS接受模块都是通过 RS232串口与 MCU进行数据传输的。这些数据包括经度、纬度、海拔高度、时间、卫星使用情况等基本信息。开发人员再依据这些基本数据,进行数据处理来完成整套的定位系统软件。 GPRMC 主要是报告接收机的经纬度、航速和航向信息,但没有高度值。 本次课程设计的目的主要是掌握系统各功能模块的基本工作原理,培养我们掌握DSP 设计的基本思路和方法
4、,掌握接收系统调试等。 课设的要 求是分析 GPS 系统各功能模块的工作原理,提出系统的设计方案,对所设计电路进行调试。在此基础上可进行创新设计,如改善电路性能;对系统进行仿 真分析。 二、 课设内容 2.1、 GPRMC 的基本原理 GPRMC 为帧头,标识后续帧内数据组成结构; 161022 为 UTC 标准时间,格式为“hh/mm/ss” ; A表示数据有效,如为 V则表示可跟踪卫星小于 3颗; 28.443546为纬度值,格式为 “ddmm mmmm” ;如 N表示北纬,为 S则表示南纬; 115.518844 为经度值,格式为 “dddmm mmmm” ;如 E表示东经,为 W则表示
5、西经; 0 0表示速度; 110 4 表示方位角,从 000 0 359 9 ; 061820 为 UTC 标准日期,格式为 “yy/mm/dd” ; 2 3表示地磁变化,从 000 O 180 0 ; W表示地磁变化方向,包括 w或 E 定位数据如经纬度 ,速度 ,时间等均可以从 SGPRMC 帧中获取得到 .SGPRMC 是 GPS推荐的最短数据 ,其帧结构为 : SGPRMC , , , , , , , , 其各字段释义如表 1所示 . 表 1 SGPRMC 帧结构及各字段释义 SGPRMCGP 为信息来源 ,RMC 为句型标识符 格林尼治时间 (UTC time):hhmmss. ss
6、s 定位状态 (A/ V): A 为有效位置 ,V 为非有效接收警 告 ,即当前天线视野上方的卫星个数少于 3 颗 经度 (Longitude): ddmm. mmm ,精确到小数点前 4位 , 后 4 位 经度方向 (S/ N):北半球 (N),南半球 (S) 纬度 (Latitude):dddmm. mmmm ,精确到小数点前 5位 , 后 4 位 纬度方向 (E/ W):东半球 (E),西半球 (W)方位角 :范围为 00010 至 35919 度; UTC日期 (Date):ddmmyy 地磁变化 :从 00010 至 18010 度校验和 (CheckSum):3hh 该帧数据的结束
7、标识符 如果此时和卫星的通信正常的话 ,可以接收到的数据为 : SGPRMC ,1612291487 , A , 372312475 , N , 1215813416 , W , 0113 , 309162 ,120598 , ,310 ;如果当前没有和卫星取得联系 ,那么字符 第 21 卷第 12期计算机应用与软件 Vol121 ,No112 2004 年 12 月 Computer Applications and SoftwareDec12004 串的格式为 : SGPRMC ,UTCTIME ,V , 例如 : SGPRMC , 062320 , V , 353718333 , N ,
8、 1394416667 , E , 00010 ,00010 ,170698 , ,30D. 2 GPS 定位数据的接收 通常 GPS 定位信息接收系统主要由 GPS 接收天线 ,变频器 ,信号通道 ,微处理器 ,存储器以及电源等部分组成 .由于 GPS定位信息内容较少 ,因此多用 RS - 232串口将定位信息 (NEMA0183 语句 )从 GPS 接收机传送到计算机中 进行信息提取处理 . 从串口读取数据有多种方法 ,既可以用 WindowsAPI 函数进行串行通信编程 ,也可以利用通信控件进行编程 .利用 API 函数编写实际应用程序时 ,往往要考虑多线程的问题 ,这样编出来的程序不但
9、十分庞大 ,而且结构比较复杂 ,继承性差 ,维护困难 .但是使用串行通信控件就相对简单一些 ,而且功能强大 ,性能安全可靠 . 通信控件 MSComm 是在 Windows 环境下实现串行通信最简单的方法 .MSComm控件不仅提供了功能完善的串口数据的发送和接受功能 ,而且它的事件驱动方式是一种功能强大的处理串行通信 方式 .使用事件驱动方式设计程序时 ,每当在通信过程中发生错误或事件 (如已接受或发送一定量字节的字符 )时 ,MSComm 控件就会引发 OnComm事件 ,OnComm事件的触发 ,就可以检测到通信中发生的错误或捕获到发生的事件 ,具体发生了什么错误或事件 ,由通信控制的
10、CommEvent 属性来判断 .CommEvent 的属性代码反映了最近发生的错误类型或事件 ,通过分别对每个 CommEvent 属性值进行编程 ,就完成了对各个错误和事件的处理 . 2.2、主要语句 txttime . Text = Data(1)/时间提取 txtLongitude . Text = Data(3)/经度提取 txtLatitude . Text = Data(5)纬度提取 txtDate . Text = Data(9)/日期提取 2.3、串口调试的基本原理和过程 1.建立项目 2.在项目中插入 MSComm 控件 3.利用 ClassWizard 定义 CMSCom
11、m 类控制变量 4.在对话框中添加控件 5.添加串口事件消息处理函数 OnComm() 6.打开和设置串口参数 7.发送数据 8.发送十六进制字符 9.在接收框中以十六进制显示 2.4、串口调试的主要程序语句 1、发送十六进制字符 在主对话框中加入一个复选接钮, ID 为 IDC_CHECK_HEXSEND Caption: 十六进制发送,再利用 ClassWizard 为其添加控制变量: m_ctrlHexSend; 在 ClassView 中为 SCommTestDlg 类添加以下两个 PUBLIC 成员函数,并输入相应代码 ; /由于这个转换函数的格式限制,在发送框中的十六制字符应该每两
12、个字符之间插入一个空隔 /如: A1 23 45 0B 00 29 /CByteArray 是一个动态字节数组,可参看 MSDN 帮助 int CSCommTestDlg:String2Hex(CString str, CByteArray int hexdatalen=0; int len=str.GetLength(); senddata.SetSize(len/2); for(int i=0;i=len) break; lstr=str; hexdata=ConvertHexChar(hstr); lowhexdata=ConvertHexChar(lstr); if(hexdata=1
13、6)|(lowhexdata=16) break; else hexdata=hexdata*16+lowhexdata; i+; senddatahexdatalen=(char)hexdata; hexdatalen+; senddata.SetSize(hexdatalen); return hexdatalen; /这是一个将字符转换为相应的十六进制值的函数 /好多 C 语言 书上都可以找到 /功能:若是在 0-F 之间的字符,则转换为相应的十六进制字符,否则返回 -1 char CSCommTestDlg:ConvertHexChar(char ch) if(ch=0) else r
14、eturn (-1); 再将 CSCommTestDlg:OnButtonManualsend()修改成以下形式: void CSCommTestDlg:OnButtonManualsend() / TODO: Add your control notification handler code here UpdateData(TRUE); /读取编辑框内容 if(m_ctrlHexSend.GetCheck() CByteArray hexdata; int len=String2Hex(m_strTXData,hexdata); /此处返回的 len可以用于计算发送了多少个十六进制数 m_
15、ctrlComm.SetOutput(COleVariant(hexdata); /发送十六进制数据 else m_ctrlComm.SetOutput(COleVariant(m_strTXData);/发送 ASCII 字符数据 现在,你先将串口线接好并打开串口调试助手 V2.1,选上以十六制显示,设置好相应串口,然后运行我们这个程序,在发送框中输入 00 01 02 03 A1 CC 等十六进制字符,并选上以十六进 制发送,单击手动发送,在串口调试助手的接收框中应该可以看到 00 01 02 03 A1 CC 了。 2、在接收框中以十六进制显示 这就容易多了: 在主对话框中加入一个复选接
16、钮, IDC_CHECK_HEXDISPLAY Caption: 十六进制显示,再利用 ClassWizard 为其添加控制变量: m_ctrlHexDiaplay。 然后修改 CSCommTestDlg:OnComm()函数: void CSCommTestDlg:OnComm() / TODO: Add your control notification handler code here VARIANT variant_inp; COleSafeArray safearray_inp; LONG len,k; BYTE rxdata2048; /设置 BYTE 数组 An 8-bit i
17、ntegerthat is not signed. CString strtemp; if(m_ctrlComm.GetCommEvent()=2) /事件值为 2表示接收缓冲区内有字符 variant_inp=m_ctrlComm.GetInput(); /读缓冲区 safearray_inp=variant_inp; /VARIANT 型变量转换为 ColeSafeArray 型变量 len=safearray_inp.GetOneDimSize(); /得到有效数据长度 for(k=0;klen;k+) safearray_inp.GetElement(/转换为 BYTE 型数组 for
18、(k=0;klen;k+) /将数组转换为 Cstring 型变量 BYTE bt=*(char*)(rxdata+k); /字符型 if(m_ctrlHexDisplay.GetCheck() strtemp.Format(“%02X “,bt); /将字符以十六进制方式送入临时变量 strtemp 存放,注意这里加入一个空隔 else strtemp.Format(“%c“,bt); /将字符送入临时变量 strtemp 存放 m_strRXData+=strtemp; /加入接收编辑框对应字符串 UpdateData(FALSE); /更新编辑框内容 测试:在串口调试助手发送框中输入 0
19、0 01 02 03 A1 CC 等十六进制字符,并选上以十六进制发送,单击手动发送,在本程序运行后选上以十六进制显示,在串口调试助手中单击手动发送或自动发送,则在本程序的接收框中应该可以看到 00 01 02 03 A1 CC 了。 3、如何设置自动发送 最简单的设定自动发送周期是用 SetTimer()函数,这在数据采集中很有用,在控制中指令的传送也可能用到定时发送。 方法是:在 ClassWizard 中选上 MessageMap 卡,然后在 Objects IDs选中 CSCommTestDlg 类, 再在 Messages 框中选上 WM_TIMER 消息,单击 ADD_FUNCTI
20、ON 加入 void CSCommTestDlg:OnTimer(UINT nIDEvent) 函数,这个函数是放入“时间到”后要处理的代码: void CSCommTestDlg:OnTimer(UINT nIDEvent) OnButtonManualsend(); CDialog:OnTimer(nIDEvent); 再在在主对话框中加入一个复选接钮, ID 为 IDC_CHECK_AUTOSEND Caption: 自动发送(周期 1 秒),再利用 ClassWizard 为其添加 BN_CLICK 消息处理函数 void CSCommTestDlg:OnCheckAutosend(): void CSCommTestDlg:OnCheckAutosend() / TODO: Add your control notification handler code here m_bAutoSend=!m_bAutoSend; if(m_bAutoSend) SetTimer(1,1000,NULL);/时间为 1000 毫秒 else KillTimer(1); /取消定时 其中: m_bAutoSend 为 BOOL 型变量,在 CLASSVIEW 中为 CSCommTestDlg 类加入,并在构造函数中初始化: m_bAutoSen=FALSE;