解析GPS数据(长字符串解析示例)


这里GPS一般返回的都是大量的数据,而且是一行行的那种,大部分数据也不太用的到,所以这个时候用串口DMA空闲中断其实就意义不大,这样我们就可以用一种新的思路来进行数据解析,专门针对这样的数据!!!

1、ATGM336H模块介绍

这里我用的大概长这样,还有很多其他版本的,不过区别不大,都差不多,可对照学习
在这里插入图片描述
参数说明:

参数详情说明
波特率:9600(默认),可用软件设置
可用卫星:GPS和北斗双模
输出协议:NMEA-0183
TXD/RXD电平:串口TTL电平
超小尺寸:15mm*13mm

这里官方还给出了输出经纬度转换的计算方法

在这里插入图片描述

2、驱动编写

在cubemx中配置如下,该模块是使用串口进行数据接受的,因此我们这里准备两个串口,其中接收数据的串口开启中断
在这里插入图片描述
之后我们根据官方数据格式编写数据结构体,同时在结构体中进行标志位等的设计
在这里插入图片描述
下面就是我们数据解析的重头戏了,不像以往空闲中断的方式,一次放入一大堆数据,这样比较吃内存,如果是数据比较规律就还好,但是如果数据里面有很多无效信息的时候,就没有必要浪费这个内存,这种采用接收中端来解析的方式就比较合适了,可以很好的处理数据,而且不会过度的占用内存,但是缺点也比较明显,就是设备会频繁的进入中断,这个是我们需要考量的因素,根据实际情况来选用!!!
在这里插入图片描述
经过上面的过程我们只是获取到了数据,并将数据放到结构体里面,但是还没有把数据把数据放到我们想要的变量里面,因此我们下面就要对这个有效数据进行进一步的处理,这里我们用到了strstr这个函数,函数的用法如下所示,就是查找函数,这里我们用来查找字符串里面的分隔符,函数的描述如下所示,根据这个方法,我们就可以很方便的获取我们需要的字符串子串。
在这里插入图片描述
下面是解析函数的使用说明,他的计算流程我已经在图中说清楚了
在这里插入图片描述
之后我们就可以解析并打印数据了,打印数据这里只是比较简单的printf函数,就不具体介绍了,详情可以查看源代码
在这里插入图片描述

这里特别注意

  • gps在室内一般是没有信号的,不要尝试在室内使用,最好是阳台,这样效果好点!
  • 第一次使用官方宣称是冷启动,耗时比较长,1-10分钟,所以不要急

3、源码

gps.c

/*
 * 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

/*
 * 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_ */

### 回答1: 对于解析GPS数据,通常需要使用特定的库或者API来处理,具体实现需要根据具体的需求而定。如果你是使用Python开发,可以考虑使用pyserial库来读取串行设备数据,并使用正则表达式或者其他方式解析GPS数据。当然,具体的实现方式也需要根据具体的GPS设备和数据格式而定。如果你有具体的需求和问题,可以跟我进一步交流。 ### 回答2: 要解析GPS数据,首先需要明确GPS数据的格式。通常,GPS数据是由若干个经纬度坐标构成的数组,每个坐标由经度和纬度值组成。在本示例中,我们使用`line`作为传入的字符串数据,表示完整的GPS数据。以下是一个解析GPS数据的算法,可以将经纬度坐标提取出来并赋值给全局变量`GPS`。 1. 首先,将`line`使用逗号分隔符拆分成单个数据项,得到一个字符串数组。 2. 创建一个空数组`coordinates`,用于存储提取的经纬度坐标。 3. 遍历字符串数组,对每个数据项执行以下操作: - 使用空格字符将数据项分隔为经度和纬度值,得到一个字符串数组`coords`。 - 将`coords`的第一个数据项(经度值)转换为浮点数类型,存储到变量`longitude`中。 - 将`coords`的第二个数据项(纬度值)转换为浮点数类型,存储到变量`latitude`中。 - 创建一个包含经度和纬度值的数组`coordinate`,并将其添加到`coordinates`数组中。 4. 将`coordinates`数组赋值给全局变量`GPS`。 以下是示例代码实现上述算法: ```python def parse_gps_data(line): data_items = line.split(',') coordinates = [] for data_item in data_items: coords = data_item.split(' ') longitude = float(coords[0]) latitude = float(coords[1]) coordinate = [longitude, latitude] coordinates.append(coordinate) return coordinates # 示例使用 line = "12.3456 78.9012,34.5678 90.1234" GPS = parse_gps_data(line) ``` 通过执行上述代码,将会解析`line`中的GPS数据,并将提取的经纬度坐标赋值给全局变量`GPS`。 ### 回答3: 要解析GPS数据,首先需要对传入的字符串数据进行处理。假设传入的字符串数据是以逗号分隔的一组值,包含经度、纬度和海拔高度等信息。 首先,我们可以使用字符串分割函数将传入的字符串数据按照逗号进行切割。切割后的结果为一个列表,列表中每个元素对应着一个数值。 然后,我们可以将切割后的列表按照顺序分别赋值给GPS的经度、纬度和海拔高度等变量。假设GPS的经度、纬度和海拔高度分别为longitude、latitude和altitude。可以通过列表索引取值的方式,将列表中对应的元素赋值给相应的变量。 最后,我们可以根据需要进行进一步的处理和使用。例如可以将经度和纬度转换为度分秒表示法,或者根据经纬度计算两个位置之间的距离等。 综上所述,通过以上步骤,我们可以解析传入的GPS数据,并将解析后的数值分别赋值给对应的全局变量,以便后续的操作和使用。
评论 64
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桃成蹊2.0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值