SPI 通信模块的设计和“基于 SPI 模块与 W25Q128 型号的 SPI FLASH 芯片通信“实践

1. 设计 SPI 模块,并将其添加入 SOPC 工程

硬件 SPI 模块的设计 SPI(Serial peripheral interface,即串行外围设备接口) SPI 是一种很常见的总线,是一种高速、同步、全双工的通讯总线。 SPI 传输速率受 限与系统时钟频率,一般最大为时钟频率的一半。 “总线”指多个设备共用的信号线。在一个 SPI 总线中,支持多个从设备。 区别于 I2C 协议中不同的从设备有不同的器件地址,这样 SPI 通过片选线 CS/NSS (SS1、SS2、SS3)选择与哪一个从机通信,如下所示,

SPI信号线 NSS: 片选信号线,主机通过拉低从机 NSS 引脚来选择从机,才能和从机通 信。 SCLK: 时钟信号线,由主机产生。SPI协议需要时钟来保证发送端和接收端的 同步传输。 MOSI(Master Ouput Slave Input): 主机(数据)输出/从设备(数据)输入引脚。 MISO(Master Input Slave Ouput): 主机(数据)输入/从设备(数据)输出引脚。 区别于 I2C 协议中只有一条 SDA 总线用于数据传输,可以看到 SPI 协议通过两 条信号线来传输数据,所以是全双工通讯,如下所示,

SPI协议介绍

起始信号、停止信号: 由前面提到的 NSS 片选线控制。 NSS 低有效。当从设 备上的 NSS 引脚被拉低表明主机选中该从设备,才能开始传输。 NSS 引脚被拉高表明传输结束。

时钟极性 CPOL/Clock Polarity

CPOL = 0:时钟空闲为低电平 0

CPOL = 1:时钟空闲为高电平1

时钟相位 CPHA /Clock Phase

CPHA = 0:在SCK的第一个跳变沿采样

CPHA = 1:在SCK的第二个跳变沿采样

SPI有四种时钟配置模式

主从双方需要工作在相同的模式下才能进行数据传输

数据传输中,SPI协议并无明确规定高位在先还是低位在先。但是主从双方要先 约定好才能进行数据传输。主机一般都采用MSB方式传输,先传输高位 LSB:least significant bit 表示二进制数据的最低位。 MSB : most significant bit 表示二进制数据的最高位。

SPI协议时序介绍 以下图为例

传输前主机先将从机的NSS拉低,作为起始信号。

时钟配置

CPOL = 0,所以时钟空闲时为低电平。

CPHA = 1,所以在SCK的第二个跳变沿,即下降沿开始采样。

在每个 SCK 周期的下降沿,通过 MOSI 和 MISO 传输一位数据。

数据一般是 8 位,采用 MSB 传输方式。在数据传输的过程中,每次接收到的数 据必须在下一次数据传输之前被采样,否则会导致 SPI 物理模块失效。因此, 在程序中传输完数据后,会去读取 SPI 设备里的数据, 即使这些数据在我们的程 序里是无用的(虽然发送后紧接着读取是无意义的,但仍然需要从寄存器中读出 来)。

区别于I2C,没有应答信号,传输结束后拉高NSS,作为停止信号。

设计一个 SPI 模块,要求如下所示,

支持全双工同步串行数据传输;

仅支持主设备工作模式;

支持 SPI 串行时钟频率的配置;

支持时钟极性和相位的配置;

仅支持 MSB 传输方式;

支持中断;

主要包括 5 个 8 位宽的寄存器:

SPI 控制寄存器

SPI 状态寄存器

SPI 发送/接收数据寄存器

SPI 外部寄存器

SPI 片选控制寄存器

SPI 有 6 个外部接口,分别是 SPI_CLK SPI_MISO SPI_MOSI SPI_CSN1 SPI_CSN2 SPI_CSN3 。这里我们只设计 SPI 主模式,所以对于 FPGA 来说, SPI_MISO 始终 是输入,其他接口始终是输出。

SPI 协议没有将读写严格区别开来,因为 SPI 的数据通道有两个,可以同时进行读 写,属于全双工通信。

主机读写数据的时序操作如下所示,

  1. 主机操作片选控制寄存器,将从机 CS 拉低。
  2.  主机操作发送数据寄存器,写入 8 bit 的数据,然后读出 8 bit 的数据。

 主机操作片选控制寄存器,将从机 CS 拉高。 我们可以将 SPI 模块作为一个 APB 外设,挂在 APB 总线上。那么就需要设计一个 APB 接口来对寄存器进行读写操作。我们需要对每个 APB 接口分配一个地址,这样 才能通过译码电路区分开来不同的 APB 。在 config.h 文件中定了 9 路 APB 地址, 默认使用 APB0 作为 GPIO ,现在我们为 SPI 模块分配 APB6 ,对应地址为 0xbfe70000 ,如下所示,

最后实现的结构框图如下所示,

在顶层文件 godson_mcu_top.v 中例化我们设计的模块,如下所示,

在约束文件中,将例化好的 SPI 的输出引脚与原理图上的合适引脚进行连接即可,如下所示,.

2. 软件设计,基于 SPI 模块与 W25Q128 型号的 SPI FLASH 芯片通信

既然已经设计好了硬件电路,我们就可以进行软件程序的编写了。在硬件 SPI 模块设 计过程中我们为 APB 分配的地址是 0xbfe90000 ,并且 SPI 相关寄存器的偏移地址 是 0x00 0x01 0x02 0x03 0x04,所以软件上需要对应好。一个不错的方法是用结构体 指针来访问寄存器。由于这个结构体指针使用频率很高,所以通过宏定义进行重命名 ( SPI ),如下所示,

编写的函数声明如下所示

然后可以基于 SPI 相函数编写 SPI 访问 W25Q128 的函数,这里以读取芯片 ID 为 例,如下所示,

我们可以在 main.c 中调用相应函数验证 SPI 通信,如下所示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值