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

该示例脚本支持 1000000500000250000125000。命令执行后应使用实际 CAN 报文确认通信,设置本身不会保存到 Flash。

选择 CAN 接口

开发板片选

Channel

发送目标

CS1

0x01

CAN-1

CS1

0x02

CAN-2

CS2

0x03

CAN-3

CS2

0x04

CAN-4

CS1 或 CS2

0x00

同时发送到当前片选对应的两路 CAN

读取到的 CAN 回包中,Channel 使用当前片选内的顺序:0x01 表示第一路,0x02 表示第二路。因此,通过 CS2 读取 CAN-3 和 CAN-4 时,回包 Channel 也会显示为 0x010x02

23 字节 SPI 报文

每次 SPI 传输包含 22 字节有效区和 1 字节 CRC:

位置

内容

字节 0~20

CAN 报文内容,不足部分填 00

字节 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

固定帧头 45 54

2

Channel

3~6

29 位 CAN ID,高字节在前

7

数据长度 08

8~15

CAN 数据,不足 8 字节填 00

16~17

固定帧尾 0D 0A

18~20

00

21

固定为 12,表示前面的有效报文长度为 18 字节

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

固定帧头 53 54

2

Channel

3~4

固定为 00 00

5~6

11 位 CAN ID,高字节在前

7

数据长度 08

8~15

CAN 数据,不足 8 字节填 00

16~17

固定帧尾 0D 0A

18~20

00

21

固定为 12

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 5453 54 开头。

开发示例

常见问题

现象

处理方法

收到的数据全为 00

这表示当前没有待读取数据;发送控制报文后稍等,再发送空报文读取

CRC 校验失败

确认 SPI 为 Mode 0、MSB First、每次 23 字节,并降低时钟或增大帧间隔

CAN 设备没有回复

检查片选、Channel、CAN ID、CAN 波特率、终端电阻、总线接线和设备供电

报文被发到了两路 CAN

Channel 为 0x00 时会同时发到当前片选对应的两路 CAN;请改为具体通道编号

高频连续发送时偶发丢帧

从 2 MHz、100 µs 帧间隔开始测试,确认稳定后再逐步提高速率