SPI 是一个非常经典的串行通信接口,常被用于 flash 读写、寄存器配置以及某些传感器数据传输等场景。相比于 uart 这种不太可靠的异步传输方式,使用同步时钟传输的 SPI 明显在性能和可靠性上提升不少。但是值得注意的是,很多地方会将 SPI 归为全双工传输,但事实上 SPI 有两种设计——标准四线和简化的三线 SPI 传输;标准的四线 SPI 确实是全双工的,但是简化的三线 SPI 是半双工的。而这又取决于其物理结构。
正如其名,四线的 SPI 仅由四根传输线组成,分别是 SCLK,CS,MOSI 和 MISO;SCLK 是时钟线,由主机发给从机,CS 是片选信号,为低有效信号,MOSI 和 MISO 也是线如其名分别是主发从收和主收从发;这也是标准的四线 SPI 可以实现全双工的原因。但是在 FPGA 的很多设计上都使用了简化的三线 SPI,SCLK 和 CS 不变,数据传输线变为 SDIO 一根,因此也只能实现半双工。
在介绍 SPI 的读写过程之前,我们需要先了解一下 SPI 的四种工作模式:
这些 Mode 也是比较有规律的,CPOL 为 0 时空闲电平为低电平,为 1 时空闲电平为高电平;CPHA 为 0 时采样边沿就是空闲电平变化的第一个边沿,为 1 时是第二边沿;更新数据边沿在采样边沿之后。
四线的读写过程比三线简单些,所以我们下面直接介绍三线的 SPI 采样过程:
写寄存器时:
1. 主机拉有效 CS。
2. 主机驱动 SDIO,发送写命令和寄存器地址。
3. 主机继续驱动 SDIO,发送数据。
4. 传输结束,主机释放 CS。
读寄存器时:
1. 主机拉有效 CS。
2. 主机驱动 SDIO,发送读命令和寄存器地址。
3. 主机关闭 SDIO 输出,让引脚进入高阻态。
4. 从机驱动 SDIO,返回数据,主机进行采样。
5. 传输结束,释放 CS。
对于这种半双工的输入输出,FPGA 中应该使用三态门来设计,xilinx 中三态门的原语是 IOBUF,其电路如下:

其真值表如下:
因此其 FPGA 原语可以这么写:
module SPI_SDIO(
input wire sdio_out, //FPGA向SDIO输出
input wire sdio_T, //三态门控制信号,此处1为FPGA控制,0为高阻
output wire sdio_in, //FPGA从SDIO读取
inout wire spi_sdio //连接从机SDIO
);
IOBUF sdio(
.I(sdio_out),
.O(sdio_in),
.IO(spi_sdio),
.T(~sdio_T)
);
endmodule
默认评论
Halo系统提供的评论