SPI 转 RS485

本协议用于 SPI 接口和 RS485 总线之间传输数据。SPI RS485 统一使用 SANPO RT 封装帧。

SANPO RT 封装帧是在原始 RS485 数据外层增加 RT / Channel / Len / CRC 路由信息。需要发送到 RS485 总线的第三方协议数据应原样放入 Data 字段,固件转发到 RS485 总线时不会解析或修改 Data 内容,只会根据 Channel 选择目标 RS485 接口,并按 Len 取出有效字节发送。

SPI RS485 支持 SHORTLONG 两种固定长度模式。

模式

总线长度

报文区长度

RS485 最大有效数据

SHORT

23 字节

22 字节

18 字节

LONG

73 字节

72 字节

68 字节

最后 1 字节为 SPI CRC;前面的字节为报文区。

SHORT 模式格式

0x52 0x54 + Channel(1B) + Len(1B) + Data(18B) + CRC(1B)

LONG 模式格式

0x52 0x54 + Channel(1B) + Len(1B) + Data(68B) + CRC(1B)

字段说明

字段

说明

0x52 0x54

ASCII RT 的十六进制表示,SANPO RT 封装帧的帧头

Channel

0x01~0x04 指定 RS485 接口;0x00 表示发送到当前 SPI 片选对应的所有 RS485 接口

Len

RS485 真实有效数据长度;SHORT 范围 0~18,LONG 范围 0~68

Data

固定长度数据区;前 Len 字节为原始 RS485 数据,固件会原样发送到 RS485 总线;其余填 0x00

CRC

SPI CRC 字节

CRC 说明

总线长度包含最后 1 字节 CRC。开发板固件使用 SPI 硬件 CRC,若主机使用软件SPI,需要生成最后 1 字节 CRC。

SHORT 示例

帧头

Channel

Len

Data

CRC

0x52 0x54

0x02

0x04

18 字节数据区,前 4 字节有效,其余补零

SPI CRC

Python 示例

完整代码样例请参考 spi_unitree_GO_M8010_demo_v6.py

def build_spi_rs485_short_payload(channel: int, payload: bytes) -> bytes:
    payload = payload[:18]
    data = payload + bytes([0x00] * (18 - len(payload)))
    body = bytes([0x52, 0x54, channel & 0xFF, len(payload)]) + data
    if len(body) != 22:
        raise ValueError("invalid SHORT payload size")
    return body

def build_spi_rs485_long_payload(channel: int, payload: bytes) -> bytes:
    payload = payload[:68]
    data = payload + bytes([0x00] * (68 - len(payload)))
    body = bytes([0x52, 0x54, channel & 0xFF, len(payload)]) + data
    if len(body) != 72:
        raise ValueError("invalid LONG payload size")
    return body