# 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接口

### 初始化函数

```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
