SANPO SPI 转 CAN
SANPO SPI 转 CAN 适合 Jetson、树莓派或其他主控板实时控制经典 CAN 设备。主控板通过固定长度的 SPI 报文发送 CAN ID 和数据,并在后续 SPI 传输中读取 CAN 设备的反馈。
建议使用 V47 或更新的 V4 固件。
SPI 连接和参数
项目 |
设置 |
|---|---|
SPI 模式 |
Mode 0 |
数据顺序 |
MSB First |
每次传输长度 |
固定 23 字节 |
建议时钟 |
从 2 MHz 开始测试 |
建议帧间隔 |
不小于 100 µs |
校验 |
第 23 字节为前 22 字节的 CRC-8 |
开发板丝印 CS1 控制 CAN-1 和 CAN-2,CS2 控制 CAN-3 和 CAN-4。在 Jetson、树莓派等 Linux 主控上,软件中的 CS0 和 CS1 通常分别连接开发板丝印的 CS1 和 CS2。
CAN 出厂默认波特率为 1 Mbps。如需更改,可以先通过 USB 使用 SANPO USB 转 CAN中的 AT+SETCAN 命令保存新参数,或参考配套示例中的 spi_set_baudrate.py。通过 SPI 临时设置的波特率在重新上电后不会保留。
例如,在 Linux 主控上将 SPI0、CS0 对应的第一路 CAN 临时设置为 500 kbit/s:
sudo python3 spi_set_baudrate.py --spibus 0 --cs 0 --mode can --cannum 1 --baudrate 500000
该示例脚本支持 1000000、500000、250000 和 125000。命令执行后应使用实际 CAN 报文确认通信,设置本身不会保存到 Flash。
选择 CAN 接口
开发板片选 |
Channel |
发送目标 |
|---|---|---|
CS1 |
|
CAN-1 |
CS1 |
|
CAN-2 |
CS2 |
|
CAN-3 |
CS2 |
|
CAN-4 |
CS1 或 CS2 |
|
同时发送到当前片选对应的两路 CAN |
读取到的 CAN 回包中,Channel 使用当前片选内的顺序:0x01 表示第一路,0x02 表示第二路。因此,通过 CS2 读取 CAN-3 和 CAN-4 时,回包 Channel 也会显示为 0x01 和 0x02。
23 字节 SPI 报文
每次 SPI 传输包含 22 字节有效区和 1 字节 CRC:
位置 |
内容 |
|---|---|
字节 0~20 |
CAN 报文内容,不足部分填 |
字节 21 |
有效报文长度 |
字节 22 |
前 22 字节的 CRC-8 |
CRC-8 使用多项式 0x07、初始值 0x00、无结果异或。
def crc8(data: bytes) -> int:
crc = 0
for value in data:
crc ^= value
for _ in range(8):
crc = ((crc << 1) ^ 0x07) & 0xFF if crc & 0x80 else (crc << 1) & 0xFF
return crc
CAN 扩展帧
发送时建议使用以下固定布局:
字节位置 |
内容 |
|---|---|
0~1 |
固定帧头 |
2 |
Channel |
3~6 |
29 位 CAN ID,高字节在前 |
7 |
数据长度 |
8~15 |
CAN 数据,不足 8 字节填 |
16~17 |
固定帧尾 |
18~20 |
填 |
21 |
固定为 |
22 |
CRC-8 |
例如,向 Channel 1、扩展帧 ID 0x0000FD01 发送 8 字节数据:
45 54 01 00 00 FD 01 08 01 00 00 00 00 00 00 00 0D 0A 00 00 00 12 FF
CAN 标准帧
字节位置 |
内容 |
|---|---|
0~1 |
固定帧头 |
2 |
Channel |
3~4 |
固定为 |
5~6 |
11 位 CAN ID,高字节在前 |
7 |
数据长度 |
8~15 |
CAN 数据,不足 8 字节填 |
16~17 |
固定帧尾 |
18~20 |
填 |
21 |
固定为 |
22 |
CRC-8 |
例如,向 Channel 1、标准帧 ID 0x142 发送 4 字节数据:
53 54 01 00 00 01 42 04 11 22 33 44 00 00 00 00 0D 0A 00 00 00 12 8C
读取 CAN 反馈
SPI 为全双工通信。发送控制报文时同时读到的内容,可能是之前已经缓存的数据或全 00。如果需要等待电机回包,应在发送后继续发送全 00 的 23 字节空报文进行读取。
读取到的有效回包应满足:
总长度为 23 字节。
字节 22 与前 22 字节的 CRC-8 一致。
字节 21 给出有效报文长度。
有效报文以
45 54或53 54开头。
开发示例
常见问题
现象 |
处理方法 |
|---|---|
收到的数据全为 |
这表示当前没有待读取数据;发送控制报文后稍等,再发送空报文读取 |
CRC 校验失败 |
确认 SPI 为 Mode 0、MSB First、每次 23 字节,并降低时钟或增大帧间隔 |
CAN 设备没有回复 |
检查片选、Channel、CAN ID、CAN 波特率、终端电阻、总线接线和设备供电 |
报文被发到了两路 CAN |
Channel 为 |
高频连续发送时偶发丢帧 |
从 2 MHz、100 µs 帧间隔开始测试,确认稳定后再逐步提高速率 |