STM_ATEM/User/GPS_Driver_Guide.md
zhoujie 5b245f89c1 feat(gps): 集成GPS模块支持数据采集系统
- 新增GPS驱动模块,支持NMEA GPGGA/GNGGA语句解析
- 修改USART3配置,波特率从2000000调整为115200用于GPS数据接收
- 新增带GPS信息的校正数据包结构`CorrectedDataPacketWithGPS_t`
- 在ADC数据处理流程中集成GPS数据获取和打包
- 更新数据包处理函数,支持GPS时间戳和经纬度信息
- 新增GPS驱动使用指南和集成说明文档
- 修改主循环,添加GPS数据处理调用
- 更新中断处理,添加GPS UART接收回调支持

📝 docs(gps): 添加GPS驱动和集成说明文档

- 新增`GPS_Driver_Guide.md`详细说明GPS驱动API和使用方法
- 新增`GPS_Integration_Guide.md`说明GPS数据集成到采集系统的实现细节
- 文档包含硬件连接、数据格式、使用示例和故障排除等内容

♻️ refactor(data): 重构数据包结构以支持GPS信息

- 修改`DataPacket_t`和`CorrectedDataPacket_t`结构,添加GPS时间戳和经纬度字段
- 新增`CorrectedDataPacketWithGPS_t`结构用于带完整GPS信息的数据包
- 更新数据打包函数,支持GPS参数传递
- 简化数据包验证逻辑,移除校验和检查以提高处理速度

🔧 chore(config): 更新硬件配置文件

- 更新STM32CubeMX项目文件,修改USART3波特率配置
- 在中断处理文件中添加GPS驱动头文件包含
2026-02-07 19:34:48 +08:00

8.9 KiB
Raw Permalink Blame History

GPS驱动使用指南

概述

本GPS驱动用于通过USART3接收GPS模块的NMEA数据主要解析GPGGA语句提取时间、经纬度、海拔高度等信息。

硬件连接

  • USART3 TX (PB10): 连接到GPS模块的RX可选如果需要向GPS发送配置命令
  • USART3 RX (PB11): 连接到GPS模块的TX接收GPS数据
  • 波特率: 9600GPS标准波特率
  • 数据格式: 8位数据位1位停止位无校验位

功能特性

1. 支持的NMEA语句

  • GPGGA: GPS定位数据主要解析
  • GNGGA: 北斗+GPS组合定位数据主要解析
  • 可扩展支持其他NMEA语句如GPRMC等

2. 解析的数据

  • 时间信息:

    • UTC时间时、分、秒、毫秒
  • 位置信息:

    • 纬度(十进制度数)
    • 纬度方向N/S
    • 经度(十进制度数)
    • 经度方向E/W
    • 海拔高度(米)
  • 定位质量:

    • 定位状态无效、GPS、DGPS、RTK等
    • 使用的卫星数量
    • 水平精度因子HDOP

3. 数据有效性管理

  • 自动检测GPS定位状态
  • 数据超时检测2秒无更新则标记为无效
  • 数据有效标志位

API接口

初始化函数

HAL_StatusTypeDef GPS_Init(void);
  • 功能: 初始化GPS驱动启动UART接收
  • 返回值: HAL_OK表示成功HAL_ERROR表示失败
  • 调用位置: 在main()函数的初始化部分调用

数据处理函数

void GPS_Process(void);
  • 功能: GPS数据处理检查数据超时
  • 调用位置: 在主循环中定期调用

获取GPS数据

uint8_t GPS_GetData(GPS_Data_t *gps_data);
  • 功能: 获取当前GPS数据
  • 参数: gps_data - 指向GPS数据结构体的指针
  • 返回值: 1表示数据有效0表示数据无效或超时

检查数据有效性

uint8_t GPS_IsDataValid(void);
  • 功能: 检查GPS数据是否有效
  • 返回值: 1表示有效0表示无效

获取格式化字符串

void GPS_GetTimeString(char *buffer, uint16_t size);
void GPS_GetPositionString(char *buffer, uint16_t size);
  • 功能: 获取格式化的GPS时间和位置字符串
  • 参数:
    • buffer - 输出缓冲区
    • size - 缓冲区大小

使用示例

基本使用流程

// 1. 在main()函数中初始化GPS
GPS_Init();

// 2. 在主循环中处理GPS数据
while (1) {
    // 处理GPS数据检查超时
    GPS_Process();
    
    // 定期获取GPS数据例如每5秒
    if (current_tick - last_gps_check >= 5000) {
        GPS_Data_t gps_data;
        if (GPS_GetData(&gps_data)) {
            // GPS数据有效可以使用
            printf("Time: %02d:%02d:%02d.%03d UTC\n",
                   gps_data.time.hour,
                   gps_data.time.minute,
                   gps_data.time.second,
                   gps_data.time.millisec);
            
            printf("Position: %.6f%c, %.6f%c\n",
                   gps_data.position.latitude,
                   gps_data.position.lat_direction,
                   gps_data.position.longitude,
                   gps_data.position.lon_direction);
            
            printf("Altitude: %.1f m\n", gps_data.position.altitude);
            printf("Satellites: %d\n", gps_data.position.satellites);
        } else {
            printf("GPS data not available\n");
        }
        last_gps_check = current_tick;
    }
}

获取格式化字符串

char time_str[64];
char pos_str[128];

GPS_GetTimeString(time_str, sizeof(time_str));
GPS_GetPositionString(pos_str, sizeof(pos_str));

// 通过串口发送
HAL_UART_Transmit(&huart1, (uint8_t*)time_str, strlen(time_str), 100);
HAL_UART_Transmit(&huart1, (uint8_t*)pos_str, strlen(pos_str), 100);

数据结构

GPS_Time_t - GPS时间结构体

typedef struct {
    uint8_t hour;       // 时 (UTC)
    uint8_t minute;     // 分
    uint8_t second;     // 秒
    uint16_t millisec;  // 毫秒
} GPS_Time_t;

GPS_Position_t - GPS位置结构体

typedef struct {
    double latitude;        // 纬度 (度)
    char lat_direction;     // 纬度方向 ('N' or 'S')
    double longitude;       // 经度 (度)
    char lon_direction;     // 经度方向 ('E' or 'W')
    double altitude;        // 海拔高度 (米)
    GPS_FixStatus_t fix_status;  // 定位状态
    uint8_t satellites;     // 使用的卫星数量
    float hdop;             // 水平精度因子
} GPS_Position_t;

GPS_Data_t - GPS数据结构体

typedef struct {
    GPS_Time_t time;            // GPS时间
    GPS_Position_t position;    // GPS位置
    uint8_t data_valid;         // 数据有效标志 (1=有效, 0=无效)
    uint32_t last_update_tick;  // 最后更新时间戳
} GPS_Data_t;

GPS_FixStatus_t - GPS定位状态枚举

typedef enum {
    GPS_FIX_INVALID = 0,    // 无效定位
    GPS_FIX_GPS = 1,        // GPS定位
    GPS_FIX_DGPS = 2,       // 差分GPS定位
    GPS_FIX_PPS = 3,        // PPS定位
    GPS_FIX_RTK = 4,        // RTK固定解
    GPS_FIX_RTK_FLOAT = 5,  // RTK浮点解
    GPS_FIX_ESTIMATED = 6,  // 估算
    GPS_FIX_MANUAL = 7,     // 手动输入
    GPS_FIX_SIMULATION = 8  // 模拟模式
} GPS_FixStatus_t;

NMEA GPGGA语句格式

GPGGA语句示例

$GPGGA,123519.00,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47

字段说明:

  • 字段0: $GPGGA - 语句标识符
  • 字段1: 123519.00 - UTC时间 (hhmmss.ss)
  • 字段2: 4807.038 - 纬度 (ddmm.mmmm)
  • 字段3: N - 纬度方向 (N/S)
  • 字段4: 01131.000 - 经度 (dddmm.mmmm)
  • 字段5: E - 经度方向 (E/W)
  • 字段6: 1 - 定位质量 (0=无效, 1=GPS, 2=DGPS, etc.)
  • 字段7: 08 - 使用的卫星数量
  • 字段8: 0.9 - HDOP水平精度因子
  • 字段9: 545.4 - 海拔高度
  • 字段10: M - 高度单位 (米)
  • 字段11-14: 其他信息
  • 字段15: *47 - 校验和

坐标转换

GPS模块输出的坐标格式为度分格式ddmm.mmmm驱动会自动转换为十进制度数格式

转换公式:

十进制度数 = 度 + (分 / 60)

示例:

  • 输入: 4807.038 N
  • 度数: 48
  • 分钟: 07.038
  • 输出: 48 + (7.038 / 60) = 48.1173°N

注意事项

  1. USART3占用: GPS驱动使用USART3因此USART3不能再用于其他功能如调试输出

  2. 波特率配置: GPS模块的波特率已配置为9600如果您的GPS模块使用其他波特率需要在usart.c中修改

  3. 数据更新频率: GPS模块通常每秒更新一次数据1Hz部分模块支持更高频率

  4. 冷启动时间: GPS模块首次启动或长时间未使用后可能需要30秒到几分钟才能获得有效定位

  5. 室内定位: GPS信号在室内通常无法接收需要在室外或窗边测试

  6. 数据有效性: 使用前务必检查GPS_IsDataValid()GPS_GetData()的返回值

  7. 中断优先级: USART3中断优先级设置为15最低优先级如需调整请在usart.c中修改

扩展功能

添加其他NMEA语句解析

如需解析其他NMEA语句如GPRMC可以在GPS_ParseNMEA()函数中添加:

static void GPS_ParseNMEA(char *nmea)
{
    if (nmea == NULL || nmea[0] != '$') {
        return;
    }
    
    // 解析GPGGA
    if (strncmp(nmea, "$GPGGA", 6) == 0 || strncmp(nmea, "$GNGGA", 6) == 0) {
        GPS_ParseGPGGA(nmea);
    }
    // 添加GPRMC解析
    else if (strncmp(nmea, "$GPRMC", 6) == 0) {
        GPS_ParseGPRMC(nmea);  // 需要实现此函数
    }
}

向GPS模块发送配置命令

如需向GPS模块发送配置命令可以使用

char cmd[] = "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n";
HAL_UART_Transmit(&huart3, (uint8_t*)cmd, strlen(cmd), 100);

故障排除

问题1: 无法接收GPS数据

  • 检查GPS模块电源是否正常
  • 检查USART3引脚连接是否正确
  • 检查GPS模块波特率是否为9600
  • 确认GPS模块在室外或窗边能接收到卫星信号

问题2: 数据一直显示无效

  • GPS模块可能需要冷启动时间30秒到几分钟
  • 检查GPS模块天线连接
  • 确认在室外或窗边测试
  • 检查GPS模块LED指示灯状态

问题3: 坐标数据不准确

  • 检查卫星数量是否足够至少4颗
  • 检查HDOP值小于2为良好
  • 等待GPS模块完全定位通常需要几分钟

文件列表

版本历史

  • v1.0 (2026-02-07)
    • 初始版本
    • 支持GPGGA/GNGGA语句解析
    • 提取时间、经纬度、海拔高度等信息
    • 数据有效性管理和超时检测

作者

  • 开发者: Your Name
  • 日期: 2026-02-07