SPI 转 CAN
本协议用于 SPI 接口收发经典 CAN 报文。SPI 为固定长度全双工协议,最后 1 字节为CRC,前面的字节为报文区。
经典 CAN 支持 SHORT 和 LONG 两种 SPI 报文模式。
经典 CAN 波特率使用 AT+SETFDCAN=<arb_baud>,<data_baud> 中的 arb_baud。data_baud 只用于 CAN FD 数据段,不影响经典 CAN。
模式 |
总线长度 |
报文区长度 |
说明 |
|---|---|---|---|
|
23 字节 |
22 字节 |
默认模式,低开销,支持经典 CAN 和 RS485。 |
|
73 字节 |
72 字节 |
使用 AT+ 指令切换,切换后下次上电保持切换状态。支持经典 CAN、CAN FD 和 RS485 |
CAN FD 请使用 SPI 转 FDCAN。
SHORT 模式格式
类型 |
帧格式 |
|---|---|
经典 CAN 扩展帧 |
|
经典 CAN 标准帧 |
|
LONG 模式格式
类型 |
帧格式 |
|---|---|
经典 CAN 扩展帧 |
|
经典 CAN 标准帧 |
|
字段说明
字段 |
说明 |
|---|---|
|
ASCII |
|
ASCII |
|
|
|
29 bit 扩展帧 CAN ID,放在 4 字节字段低 29 bit |
|
11 bit 标准帧 CAN ID,放在 2 字节字段低 11 bit |
|
标准帧 ID 前的保留字段,固定 |
|
经典 CAN 真实数据长度,范围 |
|
固定长度数据区;只有前 |
|
填充字段,固定 |
|
SPI CRC 字节 |
CRC 说明
总线长度包含最后 1 字节 CRC。固件使用硬件CRC,若主机使用软件模拟 SPI,需要按固件配置生成最后 1 字节 CRC。
Python 示例
完整代码样例请参考 spi_cybergear_demo_v6.py
def build_spi_can_ext_short_payload(channel: int, can_id: int, data: bytes) -> bytes:
if not 0 <= can_id <= 0x1FFFFFFF:
raise ValueError("extended CAN ID must be 0..0x1FFFFFFF")
data = data[:8]
data8 = data + bytes([0x00] * (8 - len(data)))
payload = bytes([0x45, 0x54, channel & 0xFF]) + can_id.to_bytes(4, "big") + bytes([len(data)]) + data8 + bytes([0x00] * 6)
if len(payload) != 22:
raise ValueError("invalid SHORT payload size")
return payload
def build_spi_can_ext_long_payload(channel: int, can_id: int, data: bytes) -> bytes:
if not 0 <= can_id <= 0x1FFFFFFF:
raise ValueError("extended CAN ID must be 0..0x1FFFFFFF")
data = data[:8]
data64 = data + bytes([0x00] * (64 - len(data)))
payload = bytes([0x45, 0x54, channel & 0xFF]) + can_id.to_bytes(4, "big") + bytes([len(data)]) + data64
if len(payload) != 72:
raise ValueError("invalid LONG payload size")
return payload