编辑 | blame | 历史 | 原始文档

GPS/IMU 数据传输协议文档

概述

本协议用于 STM32H7 (割草机MCU) 通过 UART5 向 Python 程序发送 GPS 和 IMU 数据。

  • 通信接口: UART5 (串口5)
  • 波特率: 921600 bps
  • 数据位: 8
  • 停止位: 1
  • 校验: None
  • 流控: None
  • DMA: 发送和接收均使用 DMA

数据帧格式

每个数据包采用如下格式:

+--------+--------+------+--------+--------+------+--------+--------+
| Header | Header | Type | Length | Length | Data | CRC16  | CRC16  |
|  0xAA  |  0x55  |      |  Low   |  High  |  ... |  Low   |  High  |
+--------+--------+------+--------+--------+------+--------+--------+
| Footer | Footer |
|  0x0D  |  0x0A  |
+--------+--------+

字段说明

字段 大小(字节) 说明
Header1 1 帧头1: 固定为 0xAA
Header2 1 帧头2: 固定为 0x55
Type 1 数据类型: 0x01=GPS, 0x02=IMU
Length 2 数据长度 (小端序), 不包含帧头、类型、长度、CRC和帧尾
Data N 数据负载 (结构体二进制)
CRC16 2 CRC16-MODBUS校验 (小端序), 校验范围: 从Header1到Data末尾
Footer1 1 帧尾1: 固定为 0x0D (CR)
Footer2 1 帧尾2: 固定为 0x0A (LF)

数据类型

1. GPS数据包 (Type = 0x01)

更新频率: 10 Hz (GPS模块解析成功后立即发送)

数据结构 (56 字节, 小端序):

字段 类型 偏移 大小 单位 说明
m_dLatitude double 0 8 度(°) 纬度, 正数为北纬
m_dLongitude double 8 8 度(°) 经度, 正数为东经
m_fHeadingAngle float 16 4 度(°) 航向角, 0~360, 基于东北速度计算
m_fEastVelocity float 20 4 m/s 东方向速度
m_fNorthVelocity float 24 4 m/s 北方向速度
m_fUpVelocity float 28 4 m/s 天顶方向速度
m_fAltitude float 32 4 m 高程
m_u32UTCTime uint32 36 4 hhmmss UTC时间

| m_u8PositionQuality | uint8 | 40 | 1 | - | 0=无效, 1=单点, 2=差分, 4=固定, 5=浮点 |
| m_u8SatelliteCount | uint8 | 41 | 1 | - | 可见卫星数量 |
| m_u8Reserved | uint8[2] | 42 | 2 | - | 保留字节(对齐) |

C结构体定义 (见 FML/PythonLink.h):
c typedef struct __attribute__((packed)) { HIDO_DOUBLE m_dLatitude; // 纬度(°) HIDO_DOUBLE m_dLongitude; // 经度(°) HIDO_FLOAT m_fHeadingAngle; // 航向角(°) HIDO_FLOAT m_fEastVelocity; // 东方向速度(m/s) HIDO_FLOAT m_fNorthVelocity; // 北方向速度(m/s) HIDO_FLOAT m_fUpVelocity; // 天顶方向速度(m/s) HIDO_FLOAT m_fAltitude; // 高程(m) HIDO_UINT32 m_u32UTCTime; // UTC时间 HIDO_UINT8 m_u8PositionQuality; // 定位质量 HIDO_UINT8 m_u8SatelliteCount; // 卫星数量 HIDO_UINT8 m_u8Reserved[2]; // 保留字节 } ST_PythonLink_GPS;

2. IMU数据包 (Type = 0x02)

更新频率: 100 Hz (IMU模块解析成功后立即发送)

数据结构 (32 字节, 小端序):

字段 类型 偏移 大小 单位 说明
m_fAccelX float 0 4 g X轴加速度
m_fAccelY float 4 4 g Y轴加速度
m_fAccelZ float 8 4 g Z轴加速度
m_fGyroX float 12 4 °/s X轴角速度
m_fGyroY float 16 4 °/s Y轴角速度
m_fGyroZ float 20 4 °/s Z轴角速度
m_fTemperature float 24 4 传感器温度
m_u32UTCTime uint32 28 4 ms UTC时间(毫秒)

C结构体定义 (见 FML/PythonLink.h):
c typedef struct __attribute__((packed)) { HIDO_FLOAT m_fAccelX; // X轴加速度(g) HIDO_FLOAT m_fAccelY; // Y轴加速度(g) HIDO_FLOAT m_fAccelZ; // Z轴加速度(g) HIDO_FLOAT m_fGyroX; // X轴角速度(°/s) HIDO_FLOAT m_fGyroY; // Y轴角速度(°/s) HIDO_FLOAT m_fGyroZ; // Z轴角速度(°/s) HIDO_FLOAT m_fTemperature; // 传感器温度(℃) HIDO_UINT32 m_u32UTCTime; // UTC时间(毫秒) } ST_PythonLink_IMU;

CRC16-MODBUS 校验

使用标准的 CRC16-MODBUS 算法:
- 多项式: 0x8005
- 初始值: 0xFFFF
- 结果异或值: 0x0000
- 反射输入: True
- 反射输出: True

校验范围: 从帧头 (0xAA) 到数据负载末尾 (不包含CRC和帧尾)

数据流向

STM32H7 (UART5 TX) ──────> Python (串口 RX)
                   921600 bps
                   
GPS (10Hz) ──> GPS_ParseGPRMI() ──> PythonLink_SendGPSData() ──> UART5 TX
IMU (100Hz) ─> GPS_ParseGPIMU() ──> PythonLink_SendIMUData() ──> UART5 TX

触发机制

  • GPS数据: 当 GPS_ParseGPRMI() 解析成功后, 立即调用 PythonLink_SendGPSData() 发送
  • IMU数据: 当 GPS_ParseGPIMU() 解析成功后, 立即调用 PythonLink_SendIMUData() 发送

这种机制保证了数据的**实时性** (零额外延迟), 适用于后续的电脑控制车辆实际行走场景。

Python解析示例

参见 python/gps_imu_receiver.py

安装依赖

pip install -r python/requirements.txt

运行示例

python python/gps_imu_receiver.py

修改串口配置

编辑 gps_imu_receiver.py 中的 PORTBAUDRATE:

# Windows
PORT = "COM3"

# Linux
PORT = "/dev/ttyUSB0"

# 波特率 (与STM32配置一致)
BAUDRATE = 921600

实现文件清单

STM32 固件

文件 说明
FML/PythonLink.h PythonLink 模块接口
FML/PythonLink.c PythonLink 模块实现
FML/GPS.c GPS解析, 添加了立即发送调用
HAL/Uart.h 添加了 UART_ID_PYTHON 枚举
Core/Src/main.c 注册 UART5UART_ID_PYTHON
APL/app.c 初始化和轮询 PythonLink

Python 解析器

文件 说明
python/gps_imu_receiver.py GPS/IMU 数据接收解析器
python/requirements.txt Python依赖项
PROTOCOL.md 本协议文档

注意事项

  1. 字节对齐: 所有结构体使用 __attribute__((packed)) 确保无填充字节
  2. 字节序: 所有多字节数据使用小端序 (Little Endian)
  3. 实时性: GPS 10Hz, IMU 100Hz, 解析成功后立即通过 DMA 发送
  4. DMA队列: 发送队列深度为8, 避免丢包
  5. 错误处理: Python端需处理CRC校验失败、帧丢失等异常情况

扩展性

协议预留了数据类型字段 (Type), 可方便扩展其他数据类型, 例如:
- 0x03: SBUS 遥控器数据
- 0x04: 车辆状态数据 (电池、电机等)
- 0x05: 控制命令 (Python -> STM32)

版本历史

  • v1.0 (2025-11-13): 初始版本, 支持GPS和IMU数据发送