ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

STM32的GPS数据解析程序设计说明——基于NMEA0183协议

2020-12-02 14:01:44  阅读:799  来源: 互联网

标签:发送 NMEA0183 RX STM32 串口 接收 数据 GPS


一、硬软件平台

本次程序实现效果为对GPS信号穿送来的数据进行筛选,并将筛选后的信息通过上位机显示出来,所以此次设计所需硬件包括STM32F407、RS232转TTL、CH340USB转串口模块,注意该模块在使用前,对应的系统需要安装驱动,否则串口调试助手无法识别,另外还包括JLink下载器。

本次代码设计软件为KEIL5并结合F4固件包,上位机系统为WIN7,主机系统为WIN10。

二、算法总体思路设计

由于GPS通过RS232将数据传送给板子,因此使用两个串口资源(串口1和串口2),其中一个用来接收数据,另外一个用来将筛选后的数据发送给上位机。GPS在发送信号时,相邻两次数据的发送之间有明显的时间间隔,所以该间隔可作为判断当前接收的数据是否是一个完整数据的依据。为了保证接收数据的及时性,接收数据时采用串口接收中断,发送数据则作为主程序。因此可得到以下主程序流程图。

三、具体实现步骤

3.1 串口1初始化

本次程序设计通过串口1将筛选后的数据发送给上位机,对应的硬件资源为PA9(USART1-TX)、PA10(USART1-RX)。通过将这两个IO口连接CH340,实现数据传送。串口1波特率设置为38400。

3.2 串口2初始化

串口2用来接收GPS信号,对应硬件资源为PA2(UASRT2-TX)、PA3(USART2-RX),GPS设备接口为RS232,接入单片机时,需要转为TTL电平,注意,在连接板子和RS232转TTL模块的TTL输出端时,RX和TX用反接,否则会接收不到数据。由于GPS信号发送波特率为固定的38400,所以初始化时串口2的波特率也要设置为38400。

串口2使用中断来接收数据,因为初始化时也要配置中断。具体代码如下:

图3.1 串口2中断配置

 

3.3 串口2接收中断函数

该中断函数是整个程序的重点所在,主要目的是将接收的字符存入数组内,这里数组名及大小定义为USART2_RX_BUF[NMEA_COUNT_MAX];其中将NMEA_COUNT_MAX设置为600,代表数组最大容量。当有数据发过来时,存入数组,并对该数组进行处理,若没有处理完毕,则不再接收其他数据,这里定义数据接收状态变量vu16 USART2_RX_STA。另外借助10ms定时器(TIM7)中断判断是不是一次连续的数据,如果接收连续2个字符之间的时间差不大于10ms则认为是,如果大于10ms则中断触发,强制标记数据接收完成。

图3.2  串口2中断函数

图3.3  定时器7中断函数

 

3.4数据解析

每次接收的数据都存放在数组里面,每个信息都有属于自己的标识符,例如$GNRMC、!AIVDM等,所以要找到目标信息的位置,直接对数组进行字符串搜索即可。搜索算法如下图所示,返回字符串首字符在数组中的位置。

图3.4  字符串搜索函数

 

得到目标信息的位置后,就可以提取信息中的数据了,NMEA数据的特点是信息中的数据之间都是用逗号隔开,所以逗号的数量就代表了该条信息含有多少个数据,通过数逗号的方法就可以得到每个数据。

以提取!AIVDM信息为例,其他信息提取方法相同。代码中通过宏定义的方式来选择解析和发送哪条信息。

图3.5 定义AIVDM类型数据结构

图3.6  数据解析

 

3.5 信息发送

信息发送就用普通的printf函数,不过要使用串口1函数,所以要重写一个fputs()函数,并在头文件中stdlib.h头文件。在发送之前,需要对数据进行一些简单的过滤,比较最后一个数据是信息的校验码,校验码的第二位一定是符号*等等,如果不符合过滤的条件就不发送,保证数据的正确性。

图3.7  发送函数

3.6 主函数

各个模块的功能已经实现了,接下来就可以根据图2.1编写主函数的程序,如下图所示。

图3.7  主函数大循环

 

四、遇到的问题及解决方案

4.1 数据打印前一半打印正常,后一半没有数据或者是不正确的数据

原因:在前一次数据没有解析发送完,就来了第二次数据,由于接收是采用中断方式,所以会暂停解析发送转而去接收数据,这就导致了上一次的数据被新的数据冲刷掉了,冲刷后的结果无法预测,可能没有了,可能是别的。

解决方法:参考正点原子代码。定义接收状态标志变量USART3_RX_STA,将该变量看作一个16位的寄存器,其中0-14位代表串口接收数据的长度,第15位为1时代表不接收当前数据,为0代表接受当前数据,只有当定时器中断触发时即GPS一次连续的数据已经发送完毕时,手动给该位置1,此时不再接收下一次数据,当当前数据取出后即写给另外一个数组时该位再重新置1。具体代码见图3.2和3.7。

4.2  GPS接收没数据

原因:RS232转TTL的TTL输出端与PA2,PA3反接了。

解决方法:不用反接,RX接RX,TX接TX。

五、结果

  • 参考文献
  1. http://training.eeworld.com.cn/video/18411
  2. https://blog.csdn.net/jickjiang/article/details/79086202
  3. https://blog.csdn.net/qq_33559992/article/details/52051689

标签:发送,NMEA0183,RX,STM32,串口,接收,数据,GPS
来源: https://blog.csdn.net/weixin_39954922/article/details/110479505

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有