# SPI 转 RS485
- 如下协议定义只适用于固件 V4.1 版本及以后
- 发送 AT+VER 串口指令,可以查询固件版本,如未返回版本号或者返回 V33,请下载最新固件
- 支持 SANPO 电机调试工具 快速生成调试代码,支持全系列 CAN/RS485 协议电机
## 协议说明
| 适用场景 | 接线规则 | 发送协议(SPI->RS485) | 接收协议(RS485->SPI) |
| --- | --- | --- | --- |
| RS485 协议电机(固定报文长度 23 个字节) | CS1 片选通道控制 RS485-1、RS485-2;CS2 片选通道控制 RS485-3、RS485-4 | 透传,固定长度 23 个字节,预留最后 3 个字节,最后一个字节为 CRC 值,倒数第二个字节为实际有效数据长度,倒数第三个字节为 Channel | 透传,固定长度 23 个字节,预留最后 3 个字节,最后一个字节为 CRC 值,倒数第二个字节为实际有效数据长度,倒数第三个字节为 Channel |
- RS485 协议的前两个字节不可以使用预留帧头 0x45 0x54 或者 0x41 0x54 或者 0x53 0x54,其他字节没有限制
### 报文示例
发送报文
| RS485 电机数据透传(不够 20 个字节时,使用 0x00 补齐) | Channel | 数据长度 | CRC 校验(1 字节) |
| --- | --- | --- | --- |
| 0x22 0x33 0x00 0x53 0x54 0x00 0x53 0x54 0x00 0x53 0x54 0x00 0x53 0x54 0x00 0x53 0x54 0x00 0x00 0x00 | 0x00 | 0x17 | 0x0F |
接收报文
| RS485 电机反馈数据透传 | Channel | 数据长度 | CRC 校验(1 字节) |
| --- | --- | --- | --- |
| 0x22 0x33 0x00 0x53 0x54 0x00 0x53 0x54 0x00 0x53 0x54 0x00 0x53 0x54 0x00 0x53 0x00 0x00 0x00 0x00 | 0x00 | 0x16 | 0x0F |
### 代码片段(SPI 转 RS485,Python)
完整代码样例请参考 spi_unitree_GO_M8010_demo_v4.py
```python
# 发送:电机指令数据(<=20字节,不足补0) + Channel + 数据长度 + CRC
def build_spi_rs485_frame(cmd: bytes, channel: int) -> bytes:
data_bytes = bytearray(cmd[:20])
data_len = len(data_bytes)
if data_len < 20:
data_bytes.extend([0x00] * (20 - data_len))
payload = bytes(data_bytes) + bytes([channel & 0xFF, data_len])
crc = crc8_calculator.calculate(payload)
return payload + bytes([crc]) # 固定长度23字节
tx = build_spi_rs485_frame(cmd, channel=0x00)
rx = spi.xfer2(list(tx)) # 固定长度23字节
# 接收解析:CRC 校验 + 取有效数据长度
data_part = rx[:22]
crc_ok = crc8_calculator.calculate(data_part) == rx[22]
data_len = rx[21]
motor_data = rx[:data_len]
```
## 开发样例
- SPI 转 RS485 样例程序(Python 版本):下载地址
- SPI 默认使用固定 23 个字节的收发报文