这里GPS一般返回的都是大量的数据,而且是一行行的那种,大部分数据也不太用的到,所以这个时候用串口DMA空闲中断其实就意义不大,这样我们就可以用一种新的思路来进行数据解析,专门针对这样的数据!!!
1、ATGM336H模块介绍
这里我用的大概长这样,还有很多其他版本的,不过区别不大,都差不多,可对照学习
参数说明:
参数 | 详情说明 |
---|---|
波特率: | 9600(默认),可用软件设置 |
可用卫星: | GPS和北斗双模 |
输出协议: | NMEA-0183 |
TXD/RXD电平: | 串口TTL电平 |
超小尺寸: | 15mm*13mm |
这里官方还给出了输出经纬度转换的计算方法
2、驱动编写
在cubemx中配置如下,该模块是使用串口进行数据接受的,因此我们这里准备两个串口,其中接收数据的串口开启中断
之后我们根据官方数据格式编写数据结构体,同时在结构体中进行标志位等的设计
下面就是我们数据解析的重头戏了,不像以往空闲中断的方式,一次放入一大堆数据,这样比较吃内存,如果是数据比较规律就还好,但是如果数据里面有很多无效信息的时候,就没有必要浪费这个内存,这种采用接收中端来解析的方式就比较合适了,可以很好的处理数据,而且不会过度的占用内存,但是缺点也比较明显,就是设备会频繁的进入中断,这个是我们需要考量的因素,根据实际情况来选用!!!
经过上面的过程我们只是获取到了数据,并将数据放到结构体里面,但是还没有把数据把数据放到我们想要的变量里面,因此我们下面就要对这个有效数据进行进一步的处理,这里我们用到了strstr这个函数,函数的用法如下所示,就是查找函数,这里我们用来查找字符串里面的分隔符,函数的描述如下所示,根据这个方法,我们就可以很方便的获取我们需要的字符串子串。
下面是解析函数的使用说明,他的计算流程我已经在图中说清楚了
之后我们就可以解析并打印数据了,打印数据这里只是比较简单的printf函数,就不具体介绍了,详情可以查看源代码
这里特别注意
- gps在室内一般是没有信号的,不要尝试在室内使用,最好是阳台,这样效果好点!
- 第一次使用官方宣称是冷启动,耗时比较长,1-10分钟,所以不要急
3、源码
gps.c文章来源:https://www.toymoban.com/news/detail-474627.html
/*
* gps.c
*
* Created on: Mar 25, 2022
* Author: LX
*/
#include "gps.h"
#include "string.h"
#include "stdio.h"
_SaveData Save_Data;
void errorLog(int num)
{
while (1)
{
printf("ERROR%d\r\n", num);
}
}
void clrStruct()
{
Save_Data.isGetData = 0;
Save_Data.isParseData = 0;
Save_Data.isUsefull = 0;
memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length); //清空
memset(Save_Data.UTCTime, 0, UTCTime_Length);
memset(Save_Data.latitude, 0, latitude_Length);
memset(Save_Data.N_S, 0, N_S_Length);
memset(Save_Data.longitude, 0, longitude_Length);
memset(Save_Data.E_W, 0, E_W_Length);
}
//gps数据解析
void parseGpsBuffer()
{
char *subString;
char *subStringNext;
char i = 0;
if (Save_Data.isGetData)
{
Save_Data.isGetData = 0;
printf("**************\r\n");
printf(Save_Data.GPS_Buffer);
for (i = 0; i <= 6; i++)
{
if (i == 0)
{
if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)
errorLog(1); //解析错误
}
else
{
subString++;
if ((subStringNext = strstr(subString, ",")) != NULL)
{
char usefullBuffer[2];
switch (i)
{
case 1:
memcpy(Save_Data.UTCTime, subString, subStringNext - subString);
break; //获取UTC时间
case 2:
memcpy(usefullBuffer, subString, subStringNext - subString);
break; //获取UTC时间
case 3:
memcpy(Save_Data.latitude, subString, subStringNext - subString);
break; //获取纬度信息
case 4:
memcpy(Save_Data.N_S, subString, subStringNext - subString);
break; //获取N/S
case 5:
memcpy(Save_Data.longitude, subString, subStringNext - subString);
break; //获取经度信息
case 6:
memcpy(Save_Data.E_W, subString, subStringNext - subString);
break; //获取E/W
default:
break;
}
subString = subStringNext;
Save_Data.isParseData = 1;
if (usefullBuffer[0] == 'A')
Save_Data.isUsefull = 1;
else if (usefullBuffer[0] == 'V')
Save_Data.isUsefull = 0;
}
else
{
errorLog(2); //解析错误
}
}
}
}
}
//gps数据打印
void printGpsBuffer()
{
if (Save_Data.isParseData)
{
Save_Data.isParseData = 0;
printf("Save_Data.UTCTime = ");
printf(Save_Data.UTCTime);
printf("\r\n");
if (Save_Data.isUsefull)
{
Save_Data.isUsefull = 0;
printf("Save_Data.latitude = ");
printf(Save_Data.latitude);
printf("\r\n");
printf("Save_Data.N_S = ");
printf(Save_Data.N_S);
printf("\r\n");
printf("Save_Data.longitude = ");
printf(Save_Data.longitude);
printf("\r\n");
printf("Save_Data.E_W = ");
printf(Save_Data.E_W);
printf("\r\n");
}
else
{
printf("GPS DATA is not usefull!\r\n");
}
}
}
gps.h文章来源地址https://www.toymoban.com/news/detail-474627.html
/*
* gps.h
*
* Created on: Mar 25, 2022
* Author: LX
*/
#ifndef GPS_H_
#define GPS_H_
#include "main.h"
//定义数组长度
#define GPS_Buffer_Length 80
#define UTCTime_Length 11
#define latitude_Length 11
#define N_S_Length 2
#define longitude_Length 12
#define E_W_Length 2
typedef struct SaveData
{
uint8_t GPS_Buffer[GPS_Buffer_Length];
uint8_t isGetData; //是否获取到GPS数据
uint8_t isParseData; //是否解析完成
uint8_t UTCTime[UTCTime_Length]; //UTC时间
uint8_t latitude[latitude_Length]; //纬度
uint8_t N_S[N_S_Length]; //N/S
uint8_t longitude[longitude_Length]; //经度
uint8_t E_W[E_W_Length]; //E/W
uint8_t isUsefull; //定位信息是否有效
} _SaveData;
void clrStruct();
void parseGpsBuffer();
void printGpsBuffer();
#endif /* GPS_H_ */
到了这里,关于解析GPS数据(长字符串解析示例)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!