【FPGA】SPI协议

1.SPI简介

SPI(Serial Perripheral Interface, 串行外围设备接口)是 Motorola 公司推出的一种同步串行接口技术。SPI 总线在物理上是通过接在外围设备微控制器(PICmicro) 上面的微处理控制单元 (MCU) 上叫作同步串行端口(Synchronous Serial Port) 的模块(Module)来实现的, 它允许 MCU 以全双工的同步串行方式, 与各种外围设备进行高速数据通信。

SPI接口主要应用在EEPROM、FLASH、实时时钟,AD转换器以及数字信号处理器和数字信号解码器之间。SPI是一种高速的、全双工、同步的通信总线,在芯片上只占用四根线(CS、MOSI、MISO、SCK),极大的节约了芯片的引脚。

优点 缺点
支持全双工,push-pull的驱动性能相比open-drain信号完整性更好; 相比IIC多两根线
支持高速(100MHz以上) 没有寻址机制,只能靠片选选择不同设备
协议支持字长不限于8bits,可根据应用特点灵活选择消息字长 没有从设备接受ACK,主设备对于发送成功与否不得而知
硬件连接简单 典型应用只支持单主控
相比RS232 RS485和CAN总线,SPI传输距离短

2.SPI接口

【FPGA】SPI协议_第1张图片

 4线SPI器件有四个信号:

  • 时钟(SPI CLK, SCLK)
  • 片选(CS)
  • 主机输出、从机输入(MOSI)
  • 主机输入、从机输出(MISO)

产生时钟信号的器件称为主机。主机和从机之间传输的数据与主机产生的时钟同步。同I2C接口相比, SPI器件支持更高的时钟频率。

SPI接口只能有一个主机,但可以有一个或多个从机。

上图显示了主机和从机之间的SPI连接。来自主机的片选信号用于选择从机。这通常是一个低电平有效信号,拉高时从机与SPI总线断开连接。当使用多个从机时,主机需要为每个从机提供单独的片选信号。本文中的片选信号始终是低电平有效信号。

MOSI和MISO是数据线。 MOSI将数据从主机发送到从机, MISO将数据从从机发送到主机。

【FPGA】SPI协议_第2张图片


在常规模式下,主机需要为每个从机提供单独的片选信号。一旦主机使能(拉低)片选信号, MOSI/MISO线上的时钟和数据便可用于所选的从机。如果使能多个片选信号,则MISO线上的数据会被破坏,因为主机无法识别哪个从机正在传输数据。

从图可以看出,随着从机数量的增加,来自主机的片选线的数量也增加。这会快速增加主机需要提供的输入和输出数量,并限制可以使用的从机数量。可以使用其他技术来增加常规模式下的从机数量,例如使用多路复用器产生片选信号。

【FPGA】SPI协议_第3张图片

 在菊花链模式下,所有从机的片选信号连接在一起,数据从一个从机传播到下一个从机。在此配置中,所有从机同时接收同一SPI时钟。来自主机的数据直接送到第一个从机,该从机将数据提供给下一个从机,依此类推。
使用该方法时,由于数据是从一个从机传播到下一个从机,所以传输数据所需的时钟周期数与菊花链中的从机位置成比例。例如在图7所示的8位系统中,为使第3个从机能够获得数据,需要24个时钟脉冲,而常规SPI模式下只需8个时钟脉冲。下图显示了时钟周期和通过菊花链的数据传播。并非所有SPI器件都支持菊花链模式。

【FPGA】SPI协议_第4张图片

3.SPI通信

要开始SPI通信,主机必须发送时钟信号,并通过使能CS信号选择从机。片选通常是低电平有效信号。因此,主机必须在该信号上发送逻辑0以选择从机。 SPI是全双工接口,主机和从机可以分别通过MOSI和MISO线路同时发送数据。在SPI通信期间,数据的发送(串行移出到MOSI/SDO总线上)和接收(采样或读入总线(MISO/SDI)上的数据)同时进行。串行时钟沿同步数据的移位和采样。 SPI接口允许用户灵活选择时钟的上升沿或下降沿来采样和/或移位数据。
SPI 设备间的数据传输之所以又被称为数据交换,是因为 SPI 协议规定一个 SPI 设备不能在数据通信过程中仅仅只充当一个 “发送者(Transmitter)” 或者 “接收者(Receiver)”。 在每个 Clock 周期内, SPI 设备都会发送并接收一个 bit 大小的数据, 相当于该设备有一个 bit 大小的数据被交换了。

【FPGA】SPI协议_第5张图片

 SPI主机和从机都有一个串行移位寄存器,主机通过向它的SPI串行寄存器写入一个字节来发起一次传输。

  1. 拉低对应CS信号线,表示与该设备进行通信
  2. 主机通过发送SCK时钟信号,来告诉从机写数据或者读数据。这里要注意,SCK时钟信号可能是低电平有效,也可能是高电平有效,因为SPI有四种模式,这个我们在下面会介绍
  3. 主机(Master)将要发送的数据写到发送数据缓存区(Menory),缓存区经过移位寄存器(0~7),串行移位寄存器通过MOSI信号线将字节一位一位的移出去传送给从机,同时MISO接口接收到的数据经过移位寄存器一位一位的移到接收缓存区。
  4. 从机(Slave)也将自己的串行移位寄存器(0~7)中的内容通过MISO信号线返回给主机。同时通过MOSI信号线接收主机发送的数据,这样两个移位寄存器中的内容就被交换。

SPI只有主模式和从模式之分,没有读和写的说法,外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。也就是说,你发一个数据必然会收到一个数据;你要收一个数据必须也要先发一个数据。

4.SPI时钟模式

时钟极性和时钟相位:在SPI中,主机可以通过寄存器配置选择SCK的时钟极性和时钟相位。

在空闲状态期间, CPOL位设置时钟信号的极性。空闲状态是指传输开始时CS为高电平且在向低电平转变的期间以及传输结束时CS为低电平且在向高电平转变的期间。 CPHA位选择时钟相位。根据CPHA位的状态,使用时钟上升沿或下降沿来采样和/或移位数据。主机必须根据从机的要求选择时钟极性和时钟相位。

根据CPOL和CPHA位的选择,有四种SPI模式可用。不同的从设备可能在出厂是就是配置为某种模式,这是不能改变的;但我们的通信双方必须是工作在同一模式下,所以我们可以对我们的主设备的SPI模式进行配置,通过CPOL(时钟极性)和CPHA(时钟相位)来控制我们主设备的通信模式,具体如下:

1. 时钟极性(CPOL)定义了时钟空闲状态电平:

CPOL=0,表示当SCLK=0时处于空闲态,所以有效状态就是SCLK处于高电平时
CPOL=1,表示当SCLK=1时处于空闲态,所以有效状态就是SCLK处于低电平时

2. 时钟相位(CPHA)定义数据的采集时间。

CPHA=0,在时钟的第一个跳变沿(上升沿或下降沿)进行数据采样,在第2个边沿发送数据
CPHA=1,在时钟的第二个跳变沿(上升沿或下降沿)进行数据采样,在第1个边沿发送数据
 

【FPGA】SPI协议_第6张图片

 下图显示了四种SPI模式下的通信示例。在这些示例中,数据显示在MOSI和MISO线上。传输的开始和结束用绿色虚线表示,采样边沿用橙色虚线表示,移位边沿用蓝色虚线表示。请注意,这些图形仅供参考。要成功进行SPI通信,用户须参阅产品数据手册并确保满足器件的时序规格。

【FPGA】SPI协议_第7张图片

 SPI模式0,CPOL = 0,CPHA = 0: CLK空闲状态 = 低电平,数据在上升沿采样,在下降沿移出

【FPGA】SPI协议_第8张图片

SPI模式1,CPOL = 0,CPHA = 1:CLK空闲状态=低电平,数据在下降沿采样,在上升沿移出 

【FPGA】SPI协议_第9张图片

 SPI模式2,CPOL = 1,CPHA = 1:CLK空闲状态=高电平,数据在下降沿采样,并在上升沿移出

【FPGA】SPI协议_第10张图片

 SPI模式3,CPOL = 1,CPHA = 0:CLK空闲状态=高电平,数据在上升沿采样,并在下降沿移出

5.SPI工作模式

SPI工作在3中模式下,分别是运行、等待和停止。

运行模式(Run Mode):这是基本的操作模式

等待模式(Wait Mode):SPI工作在等待模式是一种可配置的低功耗模式,可以通过SPICR2寄存器的SPISWAI位进行控制。在等待模式下,如果SPISWAI位清0,SPI操作类似于运行模式。如果SPISWAI位置1,SPI进入低功耗状态,并且SPI时钟将关闭。如果SPI配置为主机,所有的传输将停止,但是会在CPU进入运行模式后重新开始。如果SPI配置为从机,会继续接收和传输一个字节,这样就保证从机与主机同步。

停止模式(Stop Mode):为了降低功耗,SPI在停止模式是不活跃的。如果SPI配置为主机,正在进行的传输会停止,但是在CPU进入运行模式后会重新开始。如果SPI配置为从机,会继续接受和发送一个字节,这样就保证了从机与主机同步。

6.SPI读写操作

  • 标准SPI读写为例

【FPGA】SPI协议_第11张图片

  •  片选---读指令---地址---数据读出 

    【FPGA】SPI协议_第12张图片

  • 双路IO Dual I/O Fast Read Sequence Diagram  

【FPGA】SPI协议_第13张图片

  •  四路IO Quad I/O Fast Read Sequence Diagram 

【FPGA】SPI协议_第14张图片

7.SPI寄存器

Motorola定义的SPI寄存器包括:

SPI Control Register 1 (SPICR1)    控制寄存器1

SPI Control Register 2 (SPICR2)    控制寄存器2

SPI Baud Rate Register (SPIBR)    波特率寄存器

SPI Status Register (SPISR)            状态寄存器  (只读   其余均可读可写)

SPI Data Register (SPIDR)              数据寄存器

通过往寄存器中写入不同的值,设置SPI模块的不同属性。

1. 控制寄存器1 SPICR1

SPIE — SPI中断启用位
1 = SPI中断已启用
0 = SPI中断已禁用

SPE — SPI系统启用位
1 = 启用SPI,端口引脚专用于SPI功能
0 = 禁用SPI(降低功耗)

SPTIE — SPI传输中断启用
1 = SPTEF中断已启用
0 = SPTEF中断已禁用

MSTR — SPI主/从模式选择位
1 = SPI处于主模式
0 = SPI处于从属模式

CPOL — SPI时钟极性位
1 = 已选择低电平时钟。在空闲状态下,SCK高.
0 = 已选择活动的高时钟。在空闲状态下,SCK低A
.

CPHA — SPI时钟相位位
1 = 数据采样发生在SCK时钟的偶数边缘(2、4、6、…、16)
0 = 数据采样发生在SCK时钟的奇数边缘(1、3、5、…、15)

SSOE — 从属选择输出启用
SSOE 用于主设备设置SS管脚功能,它和MODFEN组合决定主设备SS管脚功能。如表1所示其功能组合:

【FPGA】SPI协议_第15张图片

LSBFE — LSB首次启用
1 = 数据首先传输最低有效位。
0 = 首先传输数据的最高有效位。

2. 控制寄存器2 SPICR2

【FPGA】SPI协议_第16张图片

MODFEN — 模式故障使能位
1 = 带MODF功能的SS端口引脚。
0 = SPI未使用SS端口引脚。

BIDIROE — 双向操作模式下的输出启用
控制双向模式(Bidirectional Mode)下主设备的MOSI和从设备MISO的输出缓冲器
1 = 输出缓冲区已启用
0 = 输出缓冲区已禁用

SPISWAI — SPI停止在等待模式位
1 = 在等待模式下停止SPI时钟生成
0 = SPI时钟在等待模式下正常工作

SPC0 — 串行引脚控制位0
控制(单个)数据管脚是否配置为双向模式,与BIDIROE组合控制(单个)数据管脚同时支持收发功能(如下表2)

【FPGA】SPI协议_第17张图片

3. 波特率寄存器 SPIBR

【FPGA】SPI协议_第18张图片

SPPR2–SPPR0 — 波特率预选位
SPR2–SPR0 — 波特率选择位

以上五个寄存器通过下面公式决定波特率除数因子(BaudRateDivisor),进而决定SCK时钟频率。

除数因子:(通过五个参数计算出来的除数因子不仅包括2^N,还包括4/6/10等总计64个组合)

计算波特率:

举例:SPPR[2:0]设为101,SPR[2:0]设为000,计算得除数因子(5+1) * (2^1) = 12。如果系统时钟速率为25MHz,则SCK时钟速率 = 25MHz/12 = 2.0833MHz.

4. 状态寄存器 SPISR

【FPGA】SPI协议_第19张图片

SPISR表征SPI传输状态,只可读,不可写。

SPIF — SPIF中断标志
数据byte写入SPI数据寄存器后,此位被置为1。读取数据寄存器后,此位清零。
1 = 新数据复制到SPIDR
0 = 传输尚未完成

SPTEF — SPI 传输空中断标志
1 = 表示发送数据寄存器为空,可以接收待发送数据
0 = 此时忽略任何写入数据寄存器的指令

MODF — 模式故障标志
如表1,错误检测功能使能后,MODF表示检测到SPI模式错误。
1 = 出现模式故障。
0 = 未发生模式故障

根据Motorola的定义,SPI仅提供一种错误——即模式错误(Mode Fault Error)——的检测机制,通过SS管脚状态判断SPI总线上是否存在两个及以上的设备同时驱动SCK和MOSI。模式错误检测仅适用于主设备(前提是在寄存器中激活此功能)。对于从设备,SS总是作为片选信号的。在发生模式错误后(MODF = 1),系统通过写入控制寄存器SPICR1(使设备由Master改为Slave模式,SCK、MISO和MOSI表现为高阻态以避免与总线上其它驱动设备冲突),随后系统自动将此bit置为零(MODF = 0)。

5. 数据寄存器 SPIDR

SPIDR作为SPI收发两用的寄存器,数据在写入SPIDR后进入待传输队列,队列中的数据字节在前面数据传输结束后立即进行传输。状态寄存器SPISR的SPTEF位表示数据寄存器可以接收新数据。数据寄存器接收数据完毕后将SPIF置为1。
如果SPIF已经置为1,但服务并未运行(not serviced),则下一个(第二个)接收的数据字节将暂存在移位寄存器中直到下次传输。数据寄存器中的数据字节不变。

如果SPIF已经置为1,并且移位寄存器中已经暂存数据(即第二个数据字节),并且SPIF服务在第三个数据字节传输前完成,则移位寄存器中的数据(即第二个数据字节 )正常写入数据寄存器,SPIF仍保持置位状态(高),如图所示;

【FPGA】SPI协议_第20张图片

如果SPIF已经置为1,并且移位寄存器中已经暂存数据(即第二个数据字节),并且SPIF服务在第三个数据字节传输后完成,则移位寄存器中的数据(即第二个数据字节 )遭破坏,不能正常写入到数据寄存器,SPIF仍保持置位状态(高),如图所示 。

【FPGA】SPI协议_第21张图片

【引用】

  1. SPI原理超详细讲解---值得一看
  2. SPI接口详细介绍_千里沽山的博客
  3. FPGA常用通信协议---SPI_工作使我快乐的博客​​​​​​
  4. FPGA(三)——基于FPGA的SPI通讯协议实现_Cilinx的博客​​​​​​
  5. 三大通信协议(3)SPI——寄存器配置_刻蓇铭鑫的博客 ​​​​​​
  6. 串行通讯SPI总线 - 知乎 (zhihu.com)

你可能感兴趣的:(FPGA学习,fpga开发)