# USB CDC串口转 RS485 USB CDC串口转 RS485 支持两种方式: - SANPO `RT` 封装帧:默认工作模式。在原始 RS485 数据外层增加 `RT / Channel / Len / 帧尾`,可逐帧指定 RS485 通道和数据长度。 - RS485 原始数据透传:兼容宇树等第三方 RS485 上位机。需要通过 `AT+RS485RAW=1` 开启,上电后默认恢复为非透传的 `RT` 封装帧模式。 生产环境建议使用 SANPO `RT` 封装帧。原始数据透传主要用于通过第三方上位机调试或设置设备参数,例如使用宇树原厂电机上位机配置电机。 ## SANPO RT 封装帧 SANPO `RT` 封装帧是 USB CDC串口侧的变长外层帧,固定以 `0x0D 0x0A` 结尾。固件收到后根据 `Channel` 选择 RS485 通道,并只把 `Data` 字段发送到 RS485 总线。 ```text 0x52 0x54 + Channel(1B) + Len(1B) + Data(0~64B) + 0x0D 0x0A ``` ## 字段说明 | 字段 | 说明 | | --- | --- | | `0x52 0x54` | ASCII `RT` 的十六进制表示,SANPO `RT` 封装帧的帧头 | | `Channel` | `0x01~0x04` 指定 RS485 接口;`0x00` 表示发送到当前设备侧所有 RS485 接口 | | `Len` | RS485 真实有效数据长度,范围 `0~64` | | `Data` | 需要发送到 RS485 总线的原始数据 | | `0x0D 0x0A` | SANPO `RT` 封装帧的帧尾 | ## SANPO RT 封装帧示例 | 帧头 | Channel | Len | Data | 帧尾 | | --- | --- | --- | --- | --- | | `0x52 0x54` | `0x02` | `0x04` | `0x22 0x33 0x01 0x02` | `0x0D 0x0A` | ## Python 示例 完整代码样例请参考 usb2rs485_unitree_sine_demo_v6.py ```python TAIL = bytes([0x0D, 0x0A]) def build_usb_rs485_rt(channel: int, payload: bytes) -> bytes: payload = payload[:64] return bytes([0x52, 0x54, channel & 0xFF, len(payload)]) + payload + TAIL ``` ## RS485 原始数据透传模式 RS485 原始数据透传模式通过 USB CDC串口 AT+ 指令控制。使用串口工具发送时,只输入命令主体,并把发送结束符设置为 `CRLF`。 | 命令 | 说明 | | --- | --- | | `AT+RS485RAW?` | 查询当前是否处于 RS485 原始数据透传模式 | | `AT+RS485RAW=1` | 开启 RS485 原始数据透传模式 | | `AT+RS485RAW=0` | 关闭 RS485 原始数据透传模式,恢复 SANPO `RT` 封装帧模式 | 固件默认处于非透传的 `RT` 封装帧模式。`AT+RS485RAW=1` 只改变当前运行状态,不作为上电默认配置保存;设备重新上电后会自动恢复为非透传模式。 开启原始数据透传后,固件不会解析第三方协议内容,也不会改写数据。上位机发送什么字节,固件就把这些字节转发到 RS485 总线;RS485 设备返回的数据内容也保持原样,上位机可以从 USB CDC串口返回数据中取出第三方协议的原始反馈。 原始数据透传没有 `Channel` 字段,默认会发送到当前设备侧所有 RS485 接口;如需指定透传目标通道,可以使用 `AT+RS485RAWCH=<0~4>`,其中 `0` 表示全部通道。 以宇树 GO-M8010-6 电机协议为例,宇树上位机发送到电机的控制帧通常以 `FE EE` 开头,电机返回的反馈帧通常以 `FD EE` 开头: ```text 宇树电机控制帧示例: FE EE 11 00 00 00 00 00 00 00 00 00 00 00 00 18 7C 宇树电机反馈帧示例: FD EE ... ``` 使用宇树原厂上位机前,先发送 `AT+RS485RAW=1` 开启 RS485 原始数据透传模式。开启后,可以把 SANPO 集成开发板的 USB CDC串口当作普通 USB 转 RS485 串口使用,不需要把宇树协议重新封装成 SANPO `RT` 封装帧。 使用串口工具手动测试宇树协议时,应使用十六进制发送模式发送原始字节,例如 `FE EE ...`。不要把 `FE EE` 当作普通文本输入,也不要额外添加 SANPO `RT` 封装帧或 `0x0D 0x0A` 帧尾。 完成第三方上位机调试或参数设置后,建议发送 `AT+RS485RAW=0` 恢复 `RT` 封装帧模式;重新上电也会自动恢复为非透传模式。 如需在生产控制中固定到某一路 RS485,建议使用 SANPO `RT` 封装帧对宇树原始协议进行封装。 使用 SANPO `RT` 封装帧对宇树原始协议进行封装时,`RT` 封装帧只作为外层路由帧,宇树协议字节仍然原样放在 `Data` 字段里。固件转发到 RS485 总线时,会去掉 `RT / Channel / Len / 帧尾`,只把 `Data` 中的宇树原始字节发送到目标 RS485 通道。 例如,下面这条宇树 GO-M8010-6 控制帧原始字节长度为 17 字节: ```text FE EE 11 00 00 00 00 00 00 00 00 00 00 00 00 18 7C ``` 如果要固定发送到 `RS485-2`,可以封装成 SANPO `RT` 封装帧: ```text 52 54 02 11 FE EE 11 00 00 00 00 00 00 00 00 00 00 00 00 18 7C 0D 0A ``` 其中 `52 54` 是 SANPO `RT` 封装帧的帧头,`02` 表示目标通道 `RS485-2`,`11` 表示后面有 17 字节宇树原始数据,末尾 `0D 0A` 是该封装帧的帧尾。RS485 总线上实际发出的仍然是中间的宇树原始数据: ```text FE EE 11 00 00 00 00 00 00 00 00 00 00 00 00 18 7C ``` 使用 SANPO `RT` 封装帧的好处是:每一帧都能明确指定 RS485 通道;同一个 USB CDC串口可以同时管理多路 RS485;第三方协议本身不需要修改,只是在外层增加 SANPO 路由信息。RS485 设备返回数据时,固件也会用 SANPO `RT` 封装帧返回,并通过 `Channel` 字段标明反馈来自哪一路 RS485。