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

323 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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接口
### 初始化函数
```c
HAL_StatusTypeDef GPS_Init(void);
```
- **功能**: 初始化GPS驱动启动UART接收
- **返回值**: HAL_OK表示成功HAL_ERROR表示失败
- **调用位置**: 在main()函数的初始化部分调用
### 数据处理函数
```c
void GPS_Process(void);
```
- **功能**: GPS数据处理检查数据超时
- **调用位置**: 在主循环中定期调用
### 获取GPS数据
```c
uint8_t GPS_GetData(GPS_Data_t *gps_data);
```
- **功能**: 获取当前GPS数据
- **参数**: gps_data - 指向GPS数据结构体的指针
- **返回值**: 1表示数据有效0表示数据无效或超时
### 检查数据有效性
```c
uint8_t GPS_IsDataValid(void);
```
- **功能**: 检查GPS数据是否有效
- **返回值**: 1表示有效0表示无效
### 获取格式化字符串
```c
void GPS_GetTimeString(char *buffer, uint16_t size);
void GPS_GetPositionString(char *buffer, uint16_t size);
```
- **功能**: 获取格式化的GPS时间和位置字符串
- **参数**:
- buffer - 输出缓冲区
- size - 缓冲区大小
## 使用示例
### 基本使用流程
```c
// 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;
}
}
```
### 获取格式化字符串
```c
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时间结构体
```c
typedef struct {
uint8_t hour; // 时 (UTC)
uint8_t minute; // 分
uint8_t second; // 秒
uint16_t millisec; // 毫秒
} GPS_Time_t;
```
### GPS_Position_t - GPS位置结构体
```c
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数据结构体
```c
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定位状态枚举
```c
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`](../Core/Src/usart.c:73)中修改
3. **数据更新频率**: GPS模块通常每秒更新一次数据1Hz部分模块支持更高频率
4. **冷启动时间**: GPS模块首次启动或长时间未使用后可能需要30秒到几分钟才能获得有效定位
5. **室内定位**: GPS信号在室内通常无法接收需要在室外或窗边测试
6. **数据有效性**: 使用前务必检查[`GPS_IsDataValid()`](gps_driver.h:95)或[`GPS_GetData()`](gps_driver.h:89)的返回值
7. **中断优先级**: USART3中断优先级设置为15最低优先级如需调整请在[`usart.c`](../Core/Src/usart.c:161)中修改
## 扩展功能
### 添加其他NMEA语句解析
如需解析其他NMEA语句如GPRMC可以在[`GPS_ParseNMEA()`](gps_driver.c:213)函数中添加:
```c
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模块发送配置命令可以使用
```c
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_driver.h:1) - GPS驱动头文件
- [`gps_driver.c`](gps_driver.c:1) - GPS驱动源文件
- [`main.c`](../Core/Src/main.c:1) - 主程序包含GPS初始化和使用示例
- [`usart.c`](../Core/Src/usart.c:1) - USART配置文件
- [`stm32f4xx_it.c`](../Core/Src/stm32f4xx_it.c:1) - 中断处理文件
## 版本历史
- **v1.0** (2026-02-07)
- 初始版本
- 支持GPGGA/GNGGA语句解析
- 提取时间、经纬度、海拔高度等信息
- 数据有效性管理和超时检测
## 作者
- 开发者: Your Name
- 日期: 2026-02-07