元驭机器人元驭机器人Hall Lab / 教学 Wiki
本页目录 12 个小节

RS485 协议

本页对应仓库内 2026-10-27 的固件快照。原工程后续版本对磁铁状态和数据有效性有更新,尚未同步到本仓库;对接实物前请核对实际固件和协议版本。

这块板通过半双工 RS485 通信,应用协议是我们自己定义的二进制格式。CRC 使用 CRC-16/MODBUS 算法,但帧头、地址和命令格式是项目自己的设计,不能直接用 Modbus RTU 主站读取。

第一次接这块板,可以先按末尾的通信步骤读一下设备信息,再对照十六进制例子看每个字段。然后换用编码器时,帧格式相同,但测量类型、单位和校准内容会变。

想对照代码看,定义在 rs485_proto.h,实际处理在 rs485_proto.c。广播等细节按实现说明。

串口与默认配置

  • MCU 串口为 USART0:PA9/TX、PA10/RX,8 数据位、无校验、1 停止位,即 8N1。
  • PB5 控制收发方向;高电平发送,低电平接收。源码说明 SIT3088 的 DE 与 RE# 接在一起。主机通常使用自动收发 USB-RS485 适配器。
  • 未保存配置或 Flash 配置校验失败时:ID=1,115200 bit/s,轮询模式,周期参数 20 ms,角度测量类型。
  • 波特率参数是索引:0→9600、1→19200、2→38400、3→57600、4→115200、5→230400、6→460800、7→921600。

依据:默认配置,第 143 行,UART 配置,第 393 行,波特率表,第 52 行。接口供电、A/B 接线和端接电阻应再对照实际硬件,软件引脚定义不能代替接线图。

帧格式

所有多字节字段均为小端;有符号整数用二进制补码。

偏移       长度    字段
0          1       A5
1          1       5A
2          1       DST:目标设备地址
3          1       SRC:源设备地址
4          1       TYPE:测量类型
5          1       CMD:命令
6          1       SEQ:8 位序号
7          1       LEN:DATA 的字节数
8          LEN     DATA
8+LEN      1       CRC 低字节
9+LEN      1       CRC 高字节

LEN≤32,整帧长 10+LEN,最大 42 字节。CRC 从 DST 开始,到 DATA 最后一个字节结束,不包含 A5 5A 和 CRC 自身。初始值 0xFFFF,逐位右移,多项式 0xA001,无最终异或;校验向量 CRC("123456789")=0x4B37,线上顺序为 37 4B。

依据:CRC,第 75 行,发送组帧,第 489 行。可用 独立教学实现 和 协议检查 重算本文实例。

先用动画看一下请求、方向切换和应答的关系。速度已放慢,不表示真实收发时序。

地址、类型和应答

  • 主机地址使用 0x00;设备 ID 为 1..254;DST=0xFF 为广播。
  • TYPE=0x01 是角度编码器,0x02 是直线位置,0xFF 是任意类型。设备只处理当前类型或 0xFF。
  • 同一总线所有传感器都应有唯一 ID。指定类型能减少不同类型误应答,不能替代唯一地址。
  • 普通应答:DST=请求SRC,SRC=设备当前ID,TYPE=当前测量类型,CMD=请求CMD|0x80,SEQ=请求SEQ。
  • 应答 DATA 第一字节是状态;状态成功才按该命令的布局解析后续内容。
  • SEQ 用于关联事务,8 位回卷;固件没有请求去重功能。超时重发的设置命令可能再次执行和写 Flash。

特别注意:SET_ID 的成功应答源地址已经是新 ID;SET_PROFILE 的成功应答类型已经是新类型。写主机时需要为这两种事务匹配预期的新标识。SET_BAUD 先按旧波特率发应答,再切到新波特率。

依据:地址与类型过滤,第 606 行,设置 ID,第 650 行,应答与波特率切换,第 967 行。

广播

固件直接忽略以下广播命令:GET_INFO、GET_DATA、GET_CAL、SET_ID、SET_BAUD、FACTORY。广播不会用于发现设备或批量分配 ID。

其余已实现设置命令可执行广播,但不回成功或错误应答;仍受 TYPE 过滤和参数检查约束。广播切换模式时应先理解其清除校准的影响。多设备教学优先采用逐台、逐地址轮询。

依据:广播排除列表,第 616 行,广播不应答,第 968 行。

命令

下文 u8/u16/i16/i32 分别是无符号 8 位、无符号 16 位、有符号 16 位和有符号 32 位。所列成功返回内容均在状态字节之后。

基本通信与配置

  • 0x01 GET_INFO:请求为空;返回类型 u8、ID u8、上传模式 u8、波特率索引 u8、周期 ms u16、固件版本 u16、校准有效 u8、标志 u8、机械零点 2 字节。应答 DATA 共 13 字节。版本常量为 0x0101,当前上位机显示为 1.1。零点在角度模式按 u16 解读,在直线模式按 i16 解读。
  • 0x02 SET_ID:请求新 ID u8,范围 1..254;成功返回新 ID u8。自动保存。
  • 0x03 SET_BAUD:请求索引 u8,范围 0..7;成功返回索引 u8。自动保存,旧波特率应答后立即切换。
  • 0x04 SET_MODE:请求上传模式 u8 加周期 ms u16;模式 0=轮询,1=主动上报,周期范围 5..60000 ms,即使模式 0 也要求周期合法。返回同样三字节。自动保存。
  • 0x05 SAVE:请求为空;保存当前配置,无额外成功数据。
  • 0x06 FACTORY:请求为空;恢复 ID=1、115200、轮询、20 ms、角度模式,清两种模式零点和校准并保存;返回新 ID u8、波特率索引 u8。若原波特率不同,同样先按旧波特率应答。
  • 0x07 SET_PROFILE:请求类型 u8,只允许 1 或 2;成功返回当前类型 u8。真正切换到另一类型时会清除两种模式的零点与校准并保存;请求已经处于的同一类型时直接返回,不清除、不重写。

依据:基本命令,第 626 行,模式切换,第 902 行,清理两种校准,第 251 行。

采样与主动上报

  • 0x10 GET_DATA:请求为空;成功应答 DATA 是 status + sample,共 14 字节。
  • 0x30 REPORT:设备主动发送,目标 0x00;DATA 仅为 sample,共 13 字节,没有状态字节。它的 SEQ 是设备独立递增的上报序号。
sample 内偏移    类型    内容
0               i32     角度或位置整数
4               i16     幅度,ADC 计数
6               u16     U1 ADC 原码
8               u16     U2 ADC 原码
10              u16     U4 ADC 原码
12              u8      flags

TYPE=1 时 value/100 为度,value×π/18000 为 rad;TYPE=2 时 value/100 为 mm,value×0.00001 为 m。变量名 angle_cdeg 在直线模式中仍被复用,不能按名字判断单位。

幅度不是磁感应强度的 T 或 mT;它是用于判断信号强弱的 ADC 计数,线上按 i16 打包且执行饱和裁剪。原码是 12 位 ADC 结果,协议用 u16 承载。

依据:采样打包,第 522 行,数据应答,第 758 行,主动上报,第 1065 行,采样结构,第 45 行。

零点、校准和直线模型宽度

  • 0x21 SET_ZERO:请求为空时捕获当前原始测量作为机械零点;也可传入 2 字节零点偏移。角度为 u16、0..35999、单位 0.01°;直线为 i16、单位 0.01 mm。它设置的是从原始读数中减掉的偏移,不是命令“当前位置显示指定数值”。返回已存零点 2 字节并自动保存。
  • 0x22 CLEAR_ZERO:请求为空;将当前模式零点设为 0,自动保存;无额外成功数据。
  • 0x23 CAL_BEGIN:请求为空;开始角度峰峰值采集或直线零磁场基线采集;此时不写 Flash。角度需转满至少一圈;直线需先拿开磁铁。
  • 0x24 CAL_END:请求为空;校准成功后自动保存,返回 offset[3](三个 i16)和 gain[3](三个 u16),DATA 共 13 字节。数据不足返回 0x04 并保持校准进行状态;未开始就结束返回 0x03。
  • 0x25 CAL_CLEAR:请求为空;清除当前模式校准并自动保存。直线回到基线 2048;零点和敏感宽度保留。
  • 0x26 GET_CAL:请求为空;返回 flags u8 + offset[3] i16 + gain[3] u16,DATA 共 14 字节。比 CAL_END 多了一个 flags,解析偏移不能共用。
  • 0x27 SET_SIGMA:仅直线模式;请求敏感宽度 u16,单位 µm、范围 2000..30000,默认 8000;返回宽度 u16 并保存。GUI 用 mm 显示,所以 8 mm 对应请求整数 8000。

角度模式的 offset 是每路偏置,gain 是 Q12 相对增益,4096=1.0。直线模式复用这些槽位:offset 为三路零磁场基线;gain[0] 为宽度 µm,gain[1] 和 gain[2] 为 0;不能把 8000 解读为 Q12 增益。

依据:零点与校准,第 768 行,GET_CAL,第 883 行,宽度设置,第 931 行,直线校准导出,第 556 行。

状态码和标志

状态码描述命令是否执行成功:

  • 0x00 成功。
  • 0x01 载荷长度错误。
  • 0x02 参数超范围。
  • 0x03 当前状态不允许,例如在角度模式设置直线宽度。
  • 0x04 校准数据不足。
  • 0x05 Flash 写入失败。
  • 0x06 未知命令。

flags 描述测量状态,多个位可同时置位:bit0/0x01 磁场弱;bit1/0x02 校准有效;bit2/0x04 校准进行中;bit3/0x08 直线超出阵列或有效插值条件。

状态成功后仍要检查弱磁、越界和校准标志。CRC 通过不代表位置正确;误差和使用条件见校准与测量。固件没有硬件采样时间戳、温度补偿质量字段或磁铁在位确认字段。

依据:状态定义,第 122 行,flags 定义,第 37 行。

收发、超时与保存

设备发帧前拉高 PB5 并用软件忙等约 50 µs,发完等待发送完成,再忙等约 50 µs 后拉低回接收。这是代码里的近似延时,应通过逻辑分析仪核对实际波形。

固件有 128 字节接收环(保留一个空槽,有效容量 127);满时新字节被丢弃,无可查询溢出计数。拼帧长超过 32、CRC 错误、地址/类型不匹配均静默丢弃,不返回错误帧;已通过 CRC 且属于本机的错误命令才可能返回状态码。主循环处理残留拼帧时,距上次处理超过 20 ms 会清掉不完整帧。

主动上报要求距最近接收和发送各至少 3 ms、本轮没有应答且不在拼帧中。这只是本机避让,没有完整总线仲裁;一条总线上同时只启用一台主动上报设备,多节点采用主机逐一轮询。

周期参数是调度目标。115200/8N1 下,23 字节上报的纯线速时间约 2.00 ms;24 字节采样应答约 2.08 ms。轮询还需 10 字节请求约 0.87 ms,以及方向切换、运算和主机延迟。9600 下同一上报约需 24 ms,所以参数允许 5 ms 不代表所有波特率都能做到 200 Hz,更不代表 ADC 同步采样频率。

写 Flash 的命令应留出不少于 100 ms 的超时;原 GUI 通常留 300–500 ms。配置实际保存为最后一页地址 0x08007C00 上的 32 字节结构,带 magic/layout/CRC。读取失败时回默认值;当前实现是擦页后写入,无双份备份或掉电事务承诺。收到 Flash 错误后应回读配置与测量状态,不假定每条命令都完整回滚。不要在采样循环重复发送保存或模式设置。

依据:发送方向,第 459 行,接收缓冲,第 425 行,拼帧恢复,第 985 行,配置保存,第 319 行。

第一次通信

  1. 单设备接入,按已知 ID 和波特率发送 GET_INFO,类型先用 ANY。
  2. 确认返回 TYPE。固件出厂默认角度;直线 PCB 应明确切换到类型 2,再重新读取信息。
  3. 按对应方法校准;直线先拿走磁铁采基线,再放回磁铁调宽度;角度转满至少一圈。
  4. 确认旗标与机械安装,设置机械零点;再用 GET_DATA 轮询采集。
  5. 主机按返回类型转换为 m 或 rad,并附主机接收时间。断链时停止产出新位置,进入上层故障处理。
  6. 更换 PCB 为角度构型后,通信帧仍可复用;切换类型、重做校准和零点,并改变单位解释。

十六进制样例

以下帧由代码构造,CRC 已与原上位机 crc16 独立核对,未连接板卡抓包。

读取 ID=1 的信息,TYPE=ANY,SEQ=1:

A5 5A 01 00 FF 01 01 00 61 8E

当前为角度类型 1 时,切换至直线类型 2,SEQ=3;成功应答已使用新类型 2:

请求:A5 5A 01 00 01 07 03 01 02 47 25
应答:A5 5A 00 01 02 87 03 02 00 02 C5 72

读取 ID=1 的直线采样,SEQ=2。构造应答值为 -1250,即 -12.50 mm=-0.0125 m;幅度 1000,U1/U2/U4 为 2048/2200/2500,flags=2:

请求:A5 5A 01 00 02 10 02 00 00 D7
应答:A5 5A 00 01 02 90 02 0E 00 1E FB FF FF E8 03 00 08 98 08 C4 09 02 59 BE

同一采样的主动帧没有状态字节,LEN=0x0D,SEQ=7:

A5 5A 00 01 02 30 07 0D 1E FB FF FF E8 03 00 08 98 08 C4 09 02 09 CA

设置直线敏感宽度 8000 µm,SEQ=6:

A5 5A 01 00 02 27 06 02 40 1F 65 62

若设备实际仍为角度类型,使用角度 TYPE 请求 SET_SIGMA 会收到状态 3;TYPE 写错成直线则会被静默忽略:

角度设备的状态错误应答:A5 5A 00 01 01 A7 06 01 03 A5 F5

设置 20 ms 主动上报和恢复 20 ms 轮询分别为:

主动:A5 5A 01 00 02 04 04 03 01 14 00 8A 60
轮询:A5 5A 01 00 02 04 05 03 00 14 00 E6 60

角度模式读数请求的对照帧(TYPE=1、SEQ=1)为 A5 5A 01 00 01 10 01 00 00 63。它与直线请求复用相同命令,数据的物理含义由类型决定。

继续阅读:上位机与独立读取示例 · 机器人接入。