SANPO SPI 转 CAN
SANPO SPI 转 CAN 适合 Jetson、树莓派或其他主控板周期控制经典 CAN 设备。主控板通过固定长度 SPI 报文发送 CAN ID 和数据,并在当前或后续传输中读取设备反馈。
CAN FD 请使用 SANPO SPI 转 FDCAN。
SPI 参数
项目 |
设置 |
|---|---|
SPI 模式 |
Mode 0(CPOL=0、CPHA=0) |
数据顺序 |
MSB First |
SHORT |
22 字节报文区 + 1 字节 CRC,共 23 字节 |
LONG |
72 字节报文区 + 1 字节 CRC,共 73 字节 |
CRC-8 |
多项式 |
出厂默认 SHORT。经典 CAN 支持 SHORT 和 LONG,但如果不需要同时使用 CAN FD,建议使用开销更小的 SHORT。
切换模式:
AT+SPIMODE=SHORT
AT+SPIMODE=LONG
命令通过 USB 串口按文本发送并以 CRLF 结尾。设置成功后会保存;主控应等待至少 10 ms,再使用新长度通信。
选择 CAN 接口
SPI 片选 |
Channel |
发送目标 |
|---|---|---|
第一颗 MCU |
|
CAN-1 |
第一颗 MCU |
|
CAN-2 |
第二颗 MCU |
|
CAN-3 |
第二颗 MCU |
|
CAN-4 |
任意片选 |
|
当前 MCU 的两路 CAN |
固件按本地接口处理:1/3 选择第一路,2/4 选择第二路。回包只使用本地 Channel 1/2。
Linux 主控中的 CS0、CS1 通常分别连接开发板的两个外部片选。应按实际接线确认,不要只依赖软件编号。
SHORT 报文
扩展帧
字节位置 |
内容 |
|---|---|
0~1 |
固定 |
2 |
Channel |
3~6 |
29 位 CAN ID,高字节在前 |
7 |
数据长度 |
8~15 |
8 字节数据区,未使用部分填 |
16~21 |
填 |
22 |
前 22 字节的 CRC-8 |
标准帧
字节位置 |
内容 |
|---|---|
0~1 |
固定 |
2 |
Channel |
3~4 |
固定 |
5~6 |
11 位 CAN ID,高字节在前 |
7 |
数据长度 |
8~15 |
8 字节数据区,未使用部分填 |
16~21 |
填 |
22 |
前 22 字节的 CRC-8 |
例如,向 Channel 1、扩展帧 ID 0x0000FD01 发送 8 字节数据时,CRC 前的 22 字节为:
45 54 01 00 00 FD 01 08 01 02 03 04 05 06 07 08 00 00 00 00 00 00
LONG 报文
LONG 的前 8 字节与 SHORT 相同,字节 8~71 为固定 64 字节数据区,最后的字节 72 为 CRC-8。经典 CAN 只使用数据区前 0~8 字节,其余填 00。
类型 |
字节 0~7 |
字节 8~71 |
字节 72 |
|---|---|---|---|
扩展帧 |
|
64 字节数据区 |
CRC-8 |
标准帧 |
|
64 字节数据区 |
CRC-8 |
计算 CRC
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
SHORT 对前 22 字节计算,LONG 对前 72 字节计算,然后把结果放在最后一个字节。
读取 CAN 反馈
SPI 是全双工接口。发送控制报文时同时读到的内容可能是之前缓存的反馈,也可能全为 00。发送后如果没有立即读到目标反馈,应继续发送同长度的全 00 空帧进行轮询。
有效反馈满足:
总长度与当前 SHORT/LONG 模式一致。
最后一个字节 CRC 正确。
报文区以
45 54或53 54开头。Channel 为本地
01或02。字节 7 给出有效 CAN 数据长度。
一次读取不是一次请求的固定应答;主控应根据 CAN ID 和电机协议识别反馈。
开发示例
常见问题
现象 |
处理方法 |
|---|---|
收到全 |
当前没有排队的反馈;稍后继续发送同长度空帧读取 |
CRC 错误 |
检查 Mode 0、MSB First、固定传输长度、SPI 时钟和片选时序 |
CAN 设备没有回复 |
检查片选、Channel、CAN ID、波特率、终端电阻、接线和供电 |
报文发到两路 CAN |
Channel 为 |
切换 LONG 后完全无响应 |
主控仍在发送 23 字节;改为每次完整发送 73 字节 |