ZHCAF60 February 2025 MSPM0G3507
在 图 2-3 和 图 2-4 中,可以看到具有协议传输功能的 CAN-SPI 桥接器的结构。图 2-3 用于 SPI 主机,图 2-4 用于 SPI 从机。CAN-SPI 桥接器可以分为四个独立的任务:从 SPI 接收、从 CAN 接收、通过 CAN 传输、通过 SPI 传输。两个 FIFO 实现双向消息传输和消息缓存。
具有透明传输功能的 CAN- SPI 桥接器的结构如 图 2-3 和 图 2-5 所示。图 2-3 用于 SPI 主机,图 2-5 用于 SPI 从机。将计时器中断添加到 CAN-SPI(SPI 目标)桥接器,以检测一个数据包结束时的超时情况。
SPI 和 CAN 接收均设置为中断触发,以便及时接收报文。进入中断时,首先通过 getXXXRxMsg() 接收消息。
对于 CAN,CAN 帧是固定格式。MSPM0 支持传统 CAN 或 CANFD。图 2-2 显示了 CANFD 帧。本文中的示例可以在协议传输的数据区域中定义 0/1/4 字节的附加 ID,如 表 2-1 所示。
图 2-2 CAN FD 帧| ID 区域 | 数据 | |
|---|---|---|
| 协议传输 | 4/1/0 字节 | (数据长度)字节 |
对于 SPI 协议传输,基于串行帧信息来识别消息。表 2-2 列出了 SPI 消息格式。
| 接头 | ID 区域 | 数据长度 | 数据 | |
|---|---|---|---|---|
| 协议传输 | 0x55 0xAA | 4/1/0 字节 | 1 字节 | (数据长度)字节 |
| 透明传输 | — | — | — | 主机到从机 - (数据长度)字节 从机到主机 - (SPI_TRANSPARENT_LENGTH) 字节 |
标头是一个固定的十六进制数,与 0x55 0xAA 组合在一起,表示组的开头。ID 区域默认占用 4 个字节,以匹配 CAN ID,可配置为 1 个字节,也可以不存在。数据长度区域占用 1 个字节。在数据长度区域之后,会跟随一定长度的数据。此格式作为示例提供。用户可以根据应用需求来修改格式。
请注意,SPI 是一种通信方法,SPI 主机负责控制发送和接收。通常,SPI 从机无法发起通信。对于 SPI 从机到主机通信,SPI 从机可以在必须发送消息时下拉 IO,如 图 2-4 中所示。当检测到 IO 为低电平时,SPI 从机可以在 IO 中断中启动 SPI 读取命令,如 图 2-3 所示。
对于 SPI 透明传输,超时发生时(在 SPI 从机上),会识别消息,如 图 2-4 所示。所有字节均视为纯数据。加载数据包信息的默认值(例如 ID)。
收到消息后,processXXXRxMsg() 会转换消息的格式,并将消息作为新元素存储在 FIFO 中。FIFO 元素的格式可以在 图 2-6 中看到。在 FIFO 元素的格式中,有 origin_id、destination_id、data length 和 data 函数。用户还可以根据应用程序要求来更改消息项目。此外,该方案还会检查 FIFO 是否已满,以进行过载控制。用户可以在需求变化时添加过载控制操作。
CAN 和 SPI 传输均在主函数中执行。当 FIFO 不为空时,将提取 FIFO 元素。消息将被格式化并发送。对于 CAN,CAN 帧为固定格式,如 表 2-1 所示。对于 SPI,消息以 SPI 数据包表单中列出的格式发送。
请注意,SPI 是一种发送和接收同步的通信方法。当主机启动发送一个字节时,主机期望接收一个字节。在本文的设计中,SPI RX 中断不仅用于 SPI 接收,还用于将 TX 数据填充到 SPI TX FIFO 中。如果 SPI 在主机模式下运行,则在 SPI TX FIFO 存入数据后,SPI 通信会立即开始。如果 SPI 在从机模式下运行,则在存储数据后,SPI 使用 IO 来触发主机以发起通信。在本演示中,用户可以选择 SPI 模式。
图 2-6 展示了 FIFO 结构。每个 FIFO 使用三个全局变量来指示 FIFO 状态。对于 gSpi2Can_FIFO,gSpi2Can_FIFO.fifo_in 表示写入位置,gSpi2Can_FIFO.fifo_out 表示读取位置,gSpi2Can_FIFO.fifo_Count 表示 gSpi2Can_FIFO 中的元素数量。
如果 gSpi2Can_FIFO 为空,则 gSpi2Can_FIFO.fifo_in 等于 gSpi2Can_FIFO.fifo_out,gSpi2Can_FIFO.fifo_count 为零。
执行 processSpiRxMsg() 时,来自 SPI 的新消息将存储到 gSpi2Can_FIFO 中。因此,gSpi2Can_FIFO.fifo 会移动到下一个位置,并且 gSpi2Can_FIFO.fifo_count 会递增 1。
从 gSpi2Can_FIFO 向 CAN 传输消息时,gSpi2Can_FIFO.fifo_out 移动到下一个位置,而 gSpi2Can_FIFO.fifo_count 减 1。gCan2Spi_FIFO 与 gSpi2Can_FIFO 类似。