USART1 串口协议规范
适用固件:MainController(STM32F103,Core/App)
端口:USART1,115200 8N1,DMA 收发
定位:精简协议规范(帧格式 / 字段 / 时序 / 状态机 / 错误处理),不含教程与案例。
教程与逐条案例解析见 串口指令说明书.md。
本文以固件代码为准;与源码注释冲突时以本文(代码实际)为准。
0. 概览
| 方向 | 帧 ID | 名称 | 长度 | 用途 |
| 下行 host→F103 | F0 06 | UWB 测距 | 10 B | 跟随数据源 |
| 下行 host→F103 | FD 03 | 串口油门 | 10 B | 双轮同速 |
| 下行 host→F103 | FD 04 | 外设直控 | 10 B | 双轮独立目标速度 + 停止模式 |
| 下行 host→F103 | FD 08 | 在线调参 | 10 B | 改写运行参数 |
| 上行 F103→host | FD 01 | 速度遥测 | 24 B | 常发 ~30 ms |
| 上行 F103→host | FD 06 | 速度链路诊断 | 24 B | 调参开关开 ~12 ms |
| 上行 F103→host | FD 07 | ADC→PWM 链路 | 24 B | 调参开关开 ~6 ms |
| 上行 F103→host | FD 0B | 跟随遥测 | 16 B | 调参开关开 ~8 ms |
• 下行固定 10 字节;上行变长 `2 + 2×n`。两者格式不同,勿混用。
1. 物理层
| 项 | 值 |
| 波特率 | 115200 |
| 帧格式 | 8 数据位 / 无校验 / 1 停止位(8N1) |
| 接收 | DMA 环形,收满 10 字节触发一次解析(缓冲 usartrx_buf,长度 10) |
| 发送 | DMA(DMA1_Channel4),忙时丢帧(dma_tx_done==0 直接丢弃,不排队) |
| 中断 | USART1 仅使能错误中断(ERR);不使用 IDLE 中断,帧对齐由软件滑窗完成 |
2. 帧层总则
2.1 下行(定长 10 字节)
• 上位机必须把每帧补齐到 10 字节(不足补 0x00),否则破坏 DMA 对齐、整帧丢失。
• 解析器在 10 字节窗口内逐字节滑窗匹配帧头(for i=0..9,环形 %10):
◦ 帧可跨缓冲边界、允许任意相位错位自对齐,无需严格对齐;
◦ 每次回调最多解析 1 帧(命中即 break),多帧连发会按 10 字节节拍逐次解开;
◦ 帧头/尾匹配不完整即整帧丢弃,不影响后续帧。
2.2 上行(变长)
• 通用格式:FD + 帧ID + n×int16(大端),整帧 = 2 + 2×n 字节。
• 上位机必须按 2 + 2×n 收帧,不能按固定 10 字节切。
• 所有 int16 由 CLAMP16 饱和到 ±32767。
2.3 字节序(方向不同,务必注意)
| 帧 | 多字节字段 |
| F0 06 UWB(下行) | 小端 |
| FD 03 / FD 04 / FD 08(下行) | 大端 |
| FD 01/06/07/0B(上行) | 大端 |
3. 下行帧定义
3.1 `F0 06` UWB 测距帧(小端,10 B)
| 偏移 | 长度 | 含义 |
| 0 | 1 | 0xF0 |
| 1 | 1 | 0x06 |
| 2–3 | 2 | 未使用 |
| 4–5 | 2 | 距离 LE16(cm) |
| 6–7 | 2 | 角度 LE16 → int16(°,>0 = 目标在左) |
| 8 | 1 | 未使用(RSSI) |
| 9 | 1 | 0xAA 尾校验 |
• 匹配条件:byte0=0xF0 && byte1=0x06 && byte9=0xAA
• 命中 → 更新距离/角度并置 RangingNew=1(触发/维持跟随)
• 无附加校验:距离在跟随侧再做 >0 && <8000 有效性判断;角度不校验范围
3.2 `FD 03` 串口油门帧(大端,10 B)
| 偏移 | 长度 | 含义 |
| 0 | 1 | 0xFD |
| 1 | 1 | 0x03 |
| 2–3 | 2 | A0 BE16,0~1000(前进) |
| 4–5 | 2 | A1 BE16,0~1000(后退) |
| 6–9 | 4 | 填充 |
行为(左=右=同一目标 cs,写入 CmdSpeed,走挡位换算):
| 条件 | cs | RunFlag | 持控制权 |
| A0>0 且 A1>0 | 0 | 0(短路制动) | 是 |
| A0>0 | +A0 | 1(前进) | 是 |
| A1>0 | −A1 | 1(后退) | 是 |
| 都 = 0 | 0 | 0 | 否(释放) |
• 量程校验:任一 >1000 → 整帧丢弃(防 0x8000 窄化变满速反转)
• 超时:见 §6.3
3.3 `FD 04` 外设直控帧(大端,10 B)
| 偏移 | 长度 | 含义 |
| 0 | 1 | 0xFD |
| 1 | 1 | 0x04 |
| 2–3 | 2 | 左轮目标 int16 BE,±1000(motor1) |
| 4–5 | 2 | 右轮目标 int16 BE,±1000(motor2) |
| 6 | 1 | 停止模式(按轮生效) |
| 7–9 | 3 | 填充 |
停止模式(偏移 6,作用于该轮目标为 0 时):
| 值 | 模式 | 该轮行为 |
| 0 | 停车 | 三相下管全导通短路制动(默认) |
| 1 | 闭环持零 | 闭环反向 PWM 主动压到 0 |
| 2 | 空挡滑行 | 释放功率级 → 自由滑行 |
• 符号:+ 前进 / − 后退 / 0 停
• 速度标定:1000 = 15.0 km/h;RefSpeed(0.1km/h) = v × 15 / 100,
解耦挡位/轮径(对照 FD 03/遥控/ADC 走挡位换算,同一 1000 ≈ 低/中/高档 4.0/6.0/10.6 km/h)
• 量程校验:|v|>1000 → 整帧丢弃;停止模式 >2 → 回落 0(停车)
• 按轮独立:一轮有目标即正常驱动,另一轮为 0 则按停止模式动作,互不影响
• 超时:见 §6.3;与 FD 03 同级、后到者优先
3.4 `FD 08` 在线调参帧(大端,10 B)
| 偏移 | 长度 | 含义 |
| 0 | 1 | 0xFD |
| 1 | 1 | 0x08 |
| 2 | 1 | PARAM_ID |
| 3–6 | 4 | VALUE,int32 BE |
| 7–9 | 3 | 填充 |
• 无完整性校验:仅匹配 FD 08 两字节即写参(噪声误匹配可能误改参数,有夹紧但不可逆)
• 参数无掉电保存,复位回默认值
• 未知/废弃 ID 落入 default,无副作用
4. 上行帧定义
字段序号为 int16 数组下标(大端)。仅 FD 01 常发;FD 06/07/0B 仅在
TuneModeEnable=1(调参开关)时发送。
4.1 `FD 01` 速度遥测(11×int16 = 24 B,~30 ms)
| # | 字段 | 单位/说明 |
| 0 | motor1.RefSpeed | 0.1 km/h |
| 1 | motor2.RefSpeed | 0.1 km/h |
| 2 | motor1.CmdSpeed | 指令量(带符号) |
| 3 | motor2.CmdSpeed | 指令量(带符号) |
| 4 | 电机1 实际施加 PWM | 带符号 = Pwm × (−RunDir) |
| 5 | 电机2 实际施加 PWM | 带符号 |
| 6 | 状态字 | bit0=Follow, bit8=RunFlag, bit12=失速1, bit13=失速2 |
| 7 | motor1.Rpm | 机械转速 |
| 8 | motor2.Rpm | 机械转速 |
| 9 | motor1.HallRaw | 霍尔 3 位(bit0=U bit1=V bit2=W) |
| 10 | motor2.HallRaw | 霍尔 3 位 |
4.2 `FD 06` 速度链路诊断(11×int16 = 24 B,~12 ms)
| # | 字段 | 说明 |
| 0 | 状态字 | bit0=SwitchDir, bit1=DIR 引脚电平, bit8–15=KeyGetDbnc |
| 1 | motor1.RotDir | 霍尔实测方向 ±1/0 |
| 2 | motor2.RotDir | 同上 |
| 3 | 状态字 | bit0=RunFlag, bit1=RcActive, bit2=Follow, bit3=刹车1, bit4=刹车2 |
| 4 | motor1.HallRaw | 三路霍尔原始编码 |
| 5 | motor2.HallRaw | 同上 |
| 6 | motor1.SectorCnt | 原始扇区计数,30 µs/计,>33333 ≈ 霍尔丢失 1 s |
| 7 | motor2.SectorCnt | 同上 |
| 8 | motor1.SectorAvg | 滤波后(已归一为 30 µs 计数;RPM = 22222 / x) |
| 9 | motor2.SectorAvg | 同上 |
| 10 | 拼装字 | bit0–3=CwChg1, bit4–7=CwChg2, bit8–11=HallRawPrev1, bit12–15=HallRawPrev2 |
4.3 `FD 07` ADC→PWM 链路 + 速度环内部量(11×int16 = 24 B,~6 ms)
| # | 字段 | 说明 |
| 0 | AdcValue1 | ADC 原始值 |
| 1 | SpeedRun | 滤波后油门 |
| 2 | motor1.SpeedOut | 速度环输出(±限幅) |
| 3 | motor2.SpeedOut | 同上 |
| 4 | 状态字 | bit0=RunFlag, bit1=AdcActive, bit2=SW1, bit3=SW2, bit4=刹车1, bit5=刹车2 |
| 5 | motor1 z1 | ×10,速度环内部量 1(0.1 km/h) |
| 6 | motor2 z1 | ×10 |
| 7 | motor1 z2 | ×10,速度环内部量 2 |
| 8 | motor2 z2 | ×10 |
| 9 | motor1 SpdFilt | ×10,真实反馈 |
| 10 | motor2 SpdFilt | ×10 |
CmdSpeed / RefSpeed / 施加 PWM / Rpm 由 FD 01 携带,此处不重复。
4.4 `FD 0B` 跟随遥测(7×int16 = 16 B,~8 ms)
| # | 字段 | 说明 |
| 0 | raw_dist | 原始测距,cm × 10 |
| 1 | raw_angle | 原始角度,° × 10(>0 = 目标在左) |
| 2 | base | 差速前进分量,0.1 km/h |
| 3 | steer | 差速转向分量,0.1 km/h |
| 4 | flags | bit0=Follow, bit1=RunFlag, bit2=目标有效 |
| 5 | motor1.ActSpeed | 0.1 km/h |
| 6 | motor2.ActSpeed | 0.1 km/h |
5. `FD 08` 参数表
raw = 下发值;写入前自动夹紧到范围。
| ID | 参数 | raw 换算 | 夹紧范围 | 默认 |
| 0x04 | 挡位速度系数(写当前挡位) | coeff × 1000 | 0.05 ~ 1.0 | 0.199 / 0.298 / 0.524 |
| 0x05 | 轮径 | cm × 1 | 16 ~ 26(越界不改) | 16 |
| 0x0C | 失速保护阈值 | 30 µs 计数 × 1 | ≥ 100 | 33333(≈1 s) |
| 0x0D | 测速保持/衰减系数 | f × 100 | 1.0 ~ 5.0 | 1.5 |
| 0x10 | 速度反馈低通(已弃用) | α × 1000 | —(写入无作用) | — |
| 0x11 | b0 对象增益 | b0 × 1000 | 0.001 ~ 5.0 | 1.8 |
| 0x12 | kp 控制器带宽 | kp × 100 | 0.01 ~ 20 | 8.0 |
| 0x13 | wo 观测器带宽 | wo × 10 | 1 ~ 500 | 20.0 |
| 0x15 | 输出限幅 | 原值 | 100 ~ 999(否则 800) | 800 |
| 0x18 | 遥控/松油门制动带宽 kp_rc | × 100 | 0.01 ~ 20 | 20.0 |
| 0x1A | 跟随转向速度比例 | × 100 | 0.1 ~ 1.0 | 1.0 |
| 0x1B | 跟随角度增益 | × 100 | 0.1 ~ 6.0 | 1.5 |
| 0x1C | 跟随目标距离 | cm × 1 | 70 ~ 150 | 85.0 |
| 0x1D | 航向 P(已弃用) | × 100 | 0 ~ 20 | — |
| 0x20 | 航向 I(已弃用) | × 100 | 0 ~ 20 | — |
| 0x22 | 跟随模式 kp | × 100 | 0.01 ~ 20 | 5.0 |
已废弃 ID(落 default 丢弃,ID 不复用):
0x01 0x02 0x03 0x06 0x07 0x08 0x0B 0x0E 0x0F 0x14 0x16 0x17 0x19 0x21 0x23 0x24
6. 控制权仲裁与状态机
6.1 仲裁链(主循环每圈,自上而下命中即停)
2.4G 遥控 RcHoldCnt>0 (独占, 忽略其余)
↓ 否则
UWB 跟随 FollowActive || RangingNew
↓ 否则
串口指令 FD 03 / FD 04 (同级, 后到者优先, 200 ms 窗口)
↓ 返回 0 且 !RcActive
本地 ADC 油门
| 层级 | 进入条件 | 备注 |
| 2.4G 遥控 | RcHoldCnt>0 | 遥控帧刷新 RcHoldCnt=3000(90 ms);独占 |
| UWB 跟随 | FollowActive 或本圈有 RangingNew | FollowCtrl() 接管 |
| 串口 | FD 03/FD 04 有新鲜帧 | 两帧共享 200 ms 窗口,谁的新帧更近谁定模式 |
| 本地 ADC | 串口级返回 0 且 RcActive==0 | RcActive 为遥控存活窗口(150 ms),防遥控帧间隙误切 ADC |
6.2 跟随状态机(`FollowCtrl` + `FollowTimeoutCheck`)
收到有效帧 (dist∈(0,8000)) ──→ 更新距离/角度, 刷新时间戳 RangingLastCnt
│
├─ dist ≥ 350cm → 退出跟随, 停车 (FollowActive=0)
├─ dist < 60cm → 退出跟随, 停车 (FollowActive=0, 防撞)
└─ 60 ≤ dist < 350 → 正常跟随:
· dist > 目标距离(85cm) : 前进 + 转向 (Stanley: 航向项 + 横向项 + ff)
· dist ≤ 目标距离 : 转向对齐/原地 pivot
· 均置 FollowActive=1 (独占, 阻挡手动/串口/ADC)
掉帧 (无有效帧) 按经过时间:
< 200 ms → 保持上次指令 (骑过瞬时丢帧)
200~400 ms → 递减至 0 (保持转向/曲率平滑减速; 每 30ms tick 按比例乘一次, 乘法累积略快于线性)
≥ 400 ms → 停车, 但 FollowActive 仍=1 继续阻挡手动
> 1 s → FollowTimeoutCheck 释放 FollowActive, 交还手动 (停车)
• 跟随决策层 base/steer 按低档物理标定,写 CmdSpeed 时乘 wk_ref/wk 解耦挡位(各挡物理速度/差速一致)
• 失联/退出/停车/超时均复位决策状态(平滑、目标运动前馈、est_valid),防止重新进入瞬间用陈旧值猛冲
• 掉帧衰减分支与正常帧分支采用同一挡位解耦系数
6.3 超时/节拍表
| 项 | 时长 | 单位换算 | 行为 |
| 遥控帧保持 RcHoldCnt | 90 ms | 3000 × 30 µs | 遥控有效窗口;递减,帧刷新 |
| 遥控存活窗口 RcActive | 150 ms | 75 × 2 ms | 遥控帧间隙内维持,防误切 ADC |
| 串口超时 | 200 ms | 6666 × 30 µs | FD 03/FD 04 共用;超时释放控制权 |
| 跟随掉帧保持 | 200 ms | — | 骑过瞬时丢帧 |
| 跟随掉帧停车 | 400 ms | — | 衰减到 0 后停车 |
| 跟随总超时 | 1 s | 33333 × 30 µs | 释放 FollowActive |
| 串口接收 | — | 10 B | DMA 环形,满 10 字节解析 1 帧 |
| FD 01 常发 | ~30 ms | 1000 × 30 µs | 不受开关限制 |
| FD 06 | ~12 ms | 400 × 30 µs | 仅调参开关 |
| FD 07 | ~6 ms | 200 × 30 µs | 仅调参开关 |
| FD 0B | ~8 ms | 267 × 30 µs | 仅调参开关 |
7. 错误处理与鲁棒性
| 场景 | 处理 |
| 下行不足 10 字节 | 破坏 DMA 对齐 → 丢帧/错帧。必须补齐 10 B |
| 下行超范围(FD 03 任一>1000、FD 04 ` | v |
| FD 04 停止模式 >2 | 回落 0(停车,最安全) |
| FD 08 未知/废弃 ID | default 丢弃,无副作用 |
| 帧错位/跨边界 | 滑窗 %10 自对齐,正常解析 |
| UART 溢出/帧错误 | CommUartErrorRecover:清 ORE/FE/NE + 读 DR + 重启 DMA 接收 |
| 上行 DMA 忙 | 本帧丢弃(不排队),下一节拍重发 |
| 参数失电 | 无掉电保存,复位回默认 |
已知薄弱点(协议层面):
1. FD 08 仅匹配 2 字节即写参,无完整性校验——调参务必在停车、安静链路下进行
2. F0 06 角度无范围校验(距离在跟随侧校验),噪声误配可能给出离谱角度
3. FD 08 写入的参数不可逆(无读回、无掉电保存)
8. 附录:常量与单位速查
| 量 | 单位 | 备注 |
| CmdSpeed | 指令量(带符号) | 油门/直控指令域 |
| FD 04 目标 | ±1000 → ±15.0 km/h | 固定比例,解耦挡位/轮径 |
| RefSpeed / ActSpeed | 0.1 km/h | 速度环目标 / 实测 |
| SpeedOut | 同 CmdSpeed 域(±限幅) | 速度环输出 |
| Rpm | rpm | 22222 / SectorCnt |
| 时间戳 RangingTimer | 30 µs / 计 | 全部节拍/超时均以此为基准 |
| WheelSize | cm | 默认 16 |
| GearCoef | ×1000 | 低/中/高 = 0.199 / 0.298 / 0.524 |
| TpFollowDist | cm | 默认 85,FD 08 0x1C 可调 |
| 跟随距离窗 | cm | (60, 350):<60 退出、≥350 停车 |
实现注意(上位机侧)
1. 下行必须补齐 10 字节(FD 03/04/08 多发 7/8 字节会丢帧)
2. 字节序:F0 06 小端,其余下行/上行大端
3. 帧 ID 一字之差即整帧丢弃(FD 03 ≠ FD 04 ≠ FD 08)
4. 上行帧变长,按 2 + 2×n 收帧
5. FD 04 固件 200 ms 无帧即释放 → 直控须周期重发(建议 100 ms)
6. FD 08 无校验、无掉电保存,调参建议停车进行