- 新增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驱动头文件包含
8.9 KiB
8.9 KiB
GPS驱动使用指南
概述
本GPS驱动用于通过USART3接收GPS模块的NMEA数据,主要解析GPGGA语句,提取时间、经纬度、海拔高度等信息。
硬件连接
- USART3 TX (PB10): 连接到GPS模块的RX(可选,如果需要向GPS发送配置命令)
- USART3 RX (PB11): 连接到GPS模块的TX(接收GPS数据)
- 波特率: 9600(GPS标准波特率)
- 数据格式: 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
注意事项
-
USART3占用: GPS驱动使用USART3,因此USART3不能再用于其他功能(如调试输出)
-
波特率配置: GPS模块的波特率已配置为9600,如果您的GPS模块使用其他波特率,需要在
usart.c中修改 -
数据更新频率: GPS模块通常每秒更新一次数据(1Hz),部分模块支持更高频率
-
冷启动时间: GPS模块首次启动或长时间未使用后,可能需要30秒到几分钟才能获得有效定位
-
室内定位: GPS信号在室内通常无法接收,需要在室外或窗边测试
-
数据有效性: 使用前务必检查
GPS_IsDataValid()或GPS_GetData()的返回值 -
中断优先级: 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模块完全定位(通常需要几分钟)
文件列表
gps_driver.h- GPS驱动头文件gps_driver.c- GPS驱动源文件main.c- 主程序(包含GPS初始化和使用示例)usart.c- USART配置文件stm32f4xx_it.c- 中断处理文件
版本历史
- v1.0 (2026-02-07)
- 初始版本
- 支持GPGGA/GNGGA语句解析
- 提取时间、经纬度、海拔高度等信息
- 数据有效性管理和超时检测
作者
- 开发者: Your Name
- 日期: 2026-02-07