- 新增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驱动头文件包含
289 lines
8.4 KiB
Markdown
289 lines
8.4 KiB
Markdown
# GPS位置信息集成说明
|
||
|
||
## 概述
|
||
|
||
GPS位置信息已成功集成到数据采集系统中。每个ADC数据包现在都包含对应的GPS时间和位置信息,实现了数据与地理位置的关联。
|
||
|
||
## 数据包结构
|
||
|
||
### CorrectedDataPacketWithGPS_t - 带GPS信息的校正数据包
|
||
|
||
```c
|
||
typedef struct __attribute__((packed)) {
|
||
uint32_t start_byte; // 包头 (4字节) = 0xFFFFFFFF
|
||
uint32_t timestamp; // 系统时间戳 (4字节)
|
||
float corrected_x; // 校正后X轴数据 (4字节)
|
||
float corrected_y; // 校正后Y轴数据 (4字节)
|
||
float corrected_z; // 校正后Z轴数据 (4字节)
|
||
// GPS信息
|
||
uint8_t gps_valid; // GPS数据有效标志 (1字节) 1=有效, 0=无效
|
||
uint8_t gps_hour; // GPS时间-时 (1字节) UTC时间
|
||
uint8_t gps_minute; // GPS时间-分 (1字节)
|
||
uint8_t gps_second; // GPS时间-秒 (1字节)
|
||
float gps_latitude; // GPS纬度 (4字节) 十进制度数
|
||
float gps_longitude; // GPS经度 (4字节) 十进制度数
|
||
float gps_altitude; // GPS海拔高度 (4字节) 米
|
||
uint8_t gps_satellites; // GPS卫星数量 (1字节)
|
||
uint8_t reserved[3]; // 保留字节 (3字节)
|
||
uint16_t checksum; // CRC16校验和 (2字节)
|
||
uint16_t end_byte; // 包尾 (2字节) = 0x0000
|
||
} CorrectedDataPacketWithGPS_t;
|
||
```
|
||
|
||
**总大小**: 48字节
|
||
|
||
### 数据包字段说明
|
||
|
||
#### 基本信息
|
||
- **start_byte**: 固定包头标识 `0xFFFFFFFF`,用于数据包同步
|
||
- **timestamp**: 系统时间戳(毫秒),从系统启动开始计时
|
||
- **corrected_x/y/z**: 经过校正算法处理后的三轴数据
|
||
|
||
#### GPS时间信息
|
||
- **gps_valid**: GPS数据有效性标志
|
||
- `1`: GPS数据有效,定位成功
|
||
- `0`: GPS数据无效或未定位
|
||
- **gps_hour**: UTC时间-小时 (0-23)
|
||
- **gps_minute**: UTC时间-分钟 (0-59)
|
||
- **gps_second**: UTC时间-秒 (0-59)
|
||
|
||
#### GPS位置信息
|
||
- **gps_latitude**: 纬度(十进制度数)
|
||
- 正值表示北纬,负值表示南纬
|
||
- 范围: -90.0 到 +90.0
|
||
- 示例: 39.9042 表示北纬39.9042°
|
||
|
||
- **gps_longitude**: 经度(十进制度数)
|
||
- 正值表示东经,负值表示西经
|
||
- 范围: -180.0 到 +180.0
|
||
- 示例: 116.4074 表示东经116.4074°
|
||
|
||
- **gps_altitude**: 海拔高度(米)
|
||
- 相对于海平面的高度
|
||
- 示例: 50.5 表示海拔50.5米
|
||
|
||
- **gps_satellites**: 当前使用的卫星数量
|
||
- 通常需要至少4颗卫星才能定位
|
||
- 卫星数量越多,定位精度越高
|
||
|
||
#### 数据完整性
|
||
- **checksum**: CRC16-MODBUS校验和,用于验证数据完整性
|
||
- **end_byte**: 固定包尾标识 `0x0000`
|
||
|
||
## 数据流程
|
||
|
||
### 1. 数据采集流程
|
||
|
||
```
|
||
ADC采样 → 校正算法 → 获取GPS数据 → 打包数据 → 发送/存储
|
||
```
|
||
|
||
### 2. 详细流程说明
|
||
|
||
1. **ADC数据采集**:
|
||
- 通过外部中断触发,4KHz采样率
|
||
- 三路LTC2508 ADC同时采样
|
||
|
||
2. **数据校正**:
|
||
- 应用校正算法处理原始ADC数据
|
||
- 得到校正后的X、Y、Z轴数据
|
||
|
||
3. **GPS数据获取**:
|
||
- 调用[`GPS_GetData()`](User/gps_driver.h:89)获取当前GPS数据
|
||
- 检查GPS数据有效性
|
||
|
||
4. **数据打包**:
|
||
- 调用[`PackCorrectedDataWithGPS()`](User/data_packet.h:46)打包数据
|
||
- 自动计算CRC16校验和
|
||
|
||
5. **数据输出**:
|
||
- **串口输出**: 通过USART1(RS485)发送数据包
|
||
- **SD卡存储**: 将数据包写入SD卡文件
|
||
|
||
## 使用示例
|
||
|
||
### 数据包解析示例(接收端)
|
||
|
||
```c
|
||
// 接收数据包
|
||
CorrectedDataPacketWithGPS_t rx_packet;
|
||
|
||
// 验证数据包
|
||
if (ValidateCorrectedPacketWithGPS(&rx_packet)) {
|
||
// 数据包有效
|
||
|
||
// 解析ADC数据
|
||
float x = rx_packet.corrected_x;
|
||
float y = rx_packet.corrected_y;
|
||
float z = rx_packet.corrected_z;
|
||
|
||
// 解析GPS数据
|
||
if (rx_packet.gps_valid) {
|
||
// GPS数据有效
|
||
printf("GPS Time: %02d:%02d:%02d UTC\n",
|
||
rx_packet.gps_hour,
|
||
rx_packet.gps_minute,
|
||
rx_packet.gps_second);
|
||
|
||
printf("Position: %.6f°, %.6f°\n",
|
||
rx_packet.gps_latitude,
|
||
rx_packet.gps_longitude);
|
||
|
||
printf("Altitude: %.1f m\n", rx_packet.gps_altitude);
|
||
printf("Satellites: %d\n", rx_packet.gps_satellites);
|
||
} else {
|
||
printf("GPS data not available\n");
|
||
}
|
||
}
|
||
```
|
||
|
||
### Python解析示例
|
||
|
||
```python
|
||
import struct
|
||
|
||
def parse_gps_packet(data):
|
||
"""解析带GPS信息的数据包"""
|
||
# 数据包格式: I I f f f B B B B f f f B 3s H H
|
||
# I=uint32, f=float, B=uint8, H=uint16, 3s=3字节
|
||
|
||
format_str = '<IIfffBBBBfffB3sHH'
|
||
packet_size = struct.calcsize(format_str)
|
||
|
||
if len(data) != packet_size:
|
||
return None
|
||
|
||
unpacked = struct.unpack(format_str, data)
|
||
|
||
packet = {
|
||
'start_byte': unpacked[0],
|
||
'timestamp': unpacked[1],
|
||
'corrected_x': unpacked[2],
|
||
'corrected_y': unpacked[3],
|
||
'corrected_z': unpacked[4],
|
||
'gps_valid': unpacked[5],
|
||
'gps_hour': unpacked[6],
|
||
'gps_minute': unpacked[7],
|
||
'gps_second': unpacked[8],
|
||
'gps_latitude': unpacked[9],
|
||
'gps_longitude': unpacked[10],
|
||
'gps_altitude': unpacked[11],
|
||
'gps_satellites': unpacked[12],
|
||
'checksum': unpacked[14],
|
||
'end_byte': unpacked[15]
|
||
}
|
||
|
||
return packet
|
||
|
||
# 使用示例
|
||
with open('data.bin', 'rb') as f:
|
||
while True:
|
||
data = f.read(48) # 读取48字节
|
||
if len(data) < 48:
|
||
break
|
||
|
||
packet = parse_gps_packet(data)
|
||
if packet and packet['gps_valid']:
|
||
print(f"Time: {packet['gps_hour']:02d}:{packet['gps_minute']:02d}:{packet['gps_second']:02d}")
|
||
print(f"Position: {packet['gps_latitude']:.6f}, {packet['gps_longitude']:.6f}")
|
||
print(f"Altitude: {packet['gps_altitude']:.1f}m")
|
||
```
|
||
|
||
## 配置选项
|
||
|
||
### 运行时配置
|
||
|
||
通过SD卡配置文件 `0:/CONFIG.TXT` 可以控制:
|
||
|
||
- **UART输出**: 是否通过串口发送数据包
|
||
- **存储功能**: 是否将数据包存储到SD卡
|
||
|
||
配置示例:
|
||
```
|
||
UART_OUTPUT=1
|
||
STORAGE_ENABLED=1
|
||
```
|
||
|
||
## 性能考虑
|
||
|
||
### 数据包大小
|
||
- 原始数据包: 24字节
|
||
- 校正数据包: 28字节
|
||
- **带GPS数据包: 48字节** ← 当前使用
|
||
|
||
### 数据速率
|
||
- ADC采样率: 4000 Hz
|
||
- 数据包速率: 4000 包/秒
|
||
- **数据流量**: 48 × 4000 = 192,000 字节/秒 ≈ 187.5 KB/s
|
||
|
||
### 存储空间
|
||
- 1小时数据量: 187.5 KB/s × 3600s ≈ 675 MB
|
||
- 1天数据量: 675 MB × 24 ≈ 16.2 GB
|
||
|
||
## GPS数据更新频率
|
||
|
||
- GPS模块更新频率: 通常为1Hz(每秒更新一次)
|
||
- ADC采样频率: 4000Hz
|
||
- **结果**: 每个GPS数据会被复制到约4000个ADC数据包中
|
||
|
||
这意味着:
|
||
- 在GPS更新之间,多个ADC数据包会包含相同的GPS信息
|
||
- GPS时间和位置信息每秒更新一次
|
||
- 如果GPS信号丢失,`gps_valid`标志会变为0
|
||
|
||
## 注意事项
|
||
|
||
### 1. GPS数据有效性
|
||
- 始终检查`gps_valid`标志
|
||
- GPS冷启动可能需要30秒到几分钟
|
||
- 室内环境GPS信号通常无效
|
||
|
||
### 2. 时间同步
|
||
- `timestamp`是系统时间戳(毫秒)
|
||
- GPS时间是UTC时间
|
||
- 需要时区转换才能得到本地时间
|
||
|
||
### 3. 坐标系统
|
||
- GPS使用WGS84坐标系统
|
||
- 纬度/经度为十进制度数格式
|
||
- 如需其他格式,需要进行坐标转换
|
||
|
||
### 4. 数据存储
|
||
- 带GPS的数据包比原始数据包大2倍
|
||
- 需要更大的SD卡容量
|
||
- 建议使用高速SD卡(Class 10或UHS-I)
|
||
|
||
## 相关文件
|
||
|
||
- [`User/gps_driver.h`](User/gps_driver.h:1) - GPS驱动头文件
|
||
- [`User/gps_driver.c`](User/gps_driver.c:1) - GPS驱动实现
|
||
- [`User/data_packet.h`](User/data_packet.h:1) - 数据包定义
|
||
- [`User/data_packet.c`](User/data_packet.c:1) - 数据包处理函数
|
||
- [`Core/Src/main.c`](Core/Src/main.c:157) - 数据处理主函数
|
||
- [`User/GPS_Driver_Guide.md`](User/GPS_Driver_Guide.md:1) - GPS驱动详细说明
|
||
|
||
## 故障排除
|
||
|
||
### 问题1: GPS数据始终无效
|
||
- 检查GPS模块连接
|
||
- 确认在室外或窗边测试
|
||
- 等待GPS冷启动完成(可能需要几分钟)
|
||
|
||
### 问题2: 数据包校验失败
|
||
- 检查数据传输是否正确
|
||
- 确认数据包大小为48字节
|
||
- 验证CRC16计算是否正确
|
||
|
||
### 问题3: 存储速度慢
|
||
- 使用高速SD卡
|
||
- 检查SD卡是否有足够空间
|
||
- 查看系统监控统计信息
|
||
|
||
## 版本历史
|
||
|
||
- **v1.0** (2026-02-07)
|
||
- 初始版本
|
||
- 实现GPS数据集成到数据包
|
||
- 支持48字节带GPS信息的数据包
|
||
- 自动获取和打包GPS数据
|