<font size="4" style="line-height: 40px;" color="red"><strong>一、SPI协议</strong></font>
<strong>1、SPI协议概括</strong>
SPI(Serial Peripheral Interface)——串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在EEPROM、FLASH、实时时钟,AD转换器以及数字信号处理器和数字信号解码器之间。SPI是一种高速,全双工,同步的通信总线,在芯片上只占用四根线(CS、MOSI、MISO、SCK),极大的节约了芯片的引脚。
<strong> 2、SPI物理层</strong>
SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或者多个从设备。图1是一个主设备一个从设备的物理连接示意图。图中SCK是由主设备发送给从的时钟,该时钟决定了主设备发送数据的速率;MOSI是主设备发送给从设备的数据;MISO是从设备发送给主设备的数据;CS是片选信号,即只有片选信号为预先规定的使能信号时(高电平或者低电平)对此芯片的操作才有效。
<center><img src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89027-1.pn…; alt="基于FPGA的SPI协议实现"></center><center><font color="#9a9a9a"><i>图1 点对点通信</i></font></center>
<center><img src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89028-2.pn…; alt="基于FPGA的SPI协议实现"></center><center><font color="#9a9a9a"><i>图2 一主多从通信</i></font></center><br>
<strong> 3、SPI协议层</strong>
SPI通信是四线串行通信,也就是说数据是一位一位传输的。这也即是SCK存在的意义,SCK提供通信所需的时钟脉冲,MOSI和MISO则基于此时钟进行数据传输。数据输出通过MOSI线,数据在时钟的上升沿或下降沿时改变,在紧接着的下降沿或者上升沿被读取。完成一位数据传输,输入也使用同样原理。这样,至少在8次时钟信号的改变(上升沿和下降沿为一次),就可以实现8位数据的传输。
需要注意的是,SCK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少要有一个主控设备。这样传输的特点:此传输方式有一个优点,与普通串行通信不同,普通的串行通信一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCK时钟线的控制可以完成对通信的控制。SPI协议还可以实现数据的交换:因为SPI的数据输入和输出线独立所以允许同时完成数据的输入和输出。不同的SPI设备的实现方式不尽相同,主要时改变和采集数据的时间不同,在时钟信号上升沿或下降沿采集有不同的定义。
SPI总线有四种工作方式(SPI0、SPI1、SPI2、SPI3),其中使用的最为广泛的是SPI0和SPI3方式。
SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果CPHA=0,在串行同步时钟的第一个跳变沿(上升沿或下降沿)数据被采集;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升沿或下降沿)数据被采集。SPI主模块和与之通信的外设时钟相位和极性应该一致。
SPI时序图详解:SPI接口有四种不同的数据传输时序,取决于CPOL和CPHA的组合。图3中给出了这四种时序,时序与CPOL和CPHA的关系也可以从图中看出。
<center><img width="600" src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89029-3.pn…; alt="基于FPGA的SPI协议实现"></center><center><font color="#9a9a9a"><i>图3 SPI四种时序</i></font></center><br>
图3中可以看出,CPOL是用来决定SCK时钟信号空闲时的电平。CPOL=0,SCK空闲时为低电平;CPOL=1,SCK空闲时为高电平。CPHA是用来决定采样输入数据MISO时刻,CPHA = 0,在第一个SCK时钟沿进行数据采样;CPHA=1,在第二个SCK时钟沿进行数据采集。(工作模式的确定:由SLAVE的工作模式确定MASTER的工作模式)。
<font size="4" style="line-height: 40px;" color="red"><strong>二、SPI协议使用举例</strong></font>
这里通过使用SPI3来实现主机发送数据。
<center><img width="600" src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89030-4.pn…; alt="基于FPGA的SPI协议实现"></center><center><font color="#9a9a9a"><i>图4 SPI3 工作模式的主机发送数据</i></font></center><br>
在SPI3模式下,CPOL = 1,CPHA = 1。SCK在空闲时为高电平,在SCK的第二个时钟沿从机进行数据的采集(只考虑主机发送情况),在SCK的第一个时钟沿发送数据MOSI。
<font size="4" style="line-height: 40px;" color="red"><strong>三、使用verilog实现SPI3工作模式的时序</strong></font>
<strong>1、SPI3模式下工作过程</strong>
如下图所示,
<center><img width="600" src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89031-5.pn…; alt=""></center><center><font color="#9a9a9a"><i>图5 SPI发送数据过程</i></font></center><br>
接下来分析图5所示SPI发送数据的过程,首先在复位信号到来时,进入s0状态,在s0状态计数器和分频器模块加载初始值,如果发送数据开始信号spi_start有效进入s1状态,s1状态加载待发送的数据,同时计数器计数计数,分频器开始工作,如果i=1,进入s2状态,s2状态主要用来发送数据,如果i为偶数,进入s3状态,该状态是用来采集数据,由于只考虑发送,因此此模块不进行数据采集工作,如果i=15,进入s4状态,否则如果i为奇数,则进入s2状态。;在s4状态,发送最后一位数据,如果i=16,进入s5状态,此时整个SPI时序模拟完成。
<strong>2、数据路径</strong>
由图5可知,构成SPI发送时序的基本电路块包括计数器,移位寄存器和触发器模块。
<center><img width="600" src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89032-6.pn…; alt=""></center><center><font color="#9a9a9a"><i>图6 数据路径</i></font></center><br>
图6中,左移寄存器将8位的待发送的数据spi_data转换为串行的数据mosi一位一位的发送出去,计数器用来计数发送数据的个数,触发器用来产生分频后的sck时钟信号。
<strong>3、控制信号</strong>
<center><img src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89033-7.pn…; alt=""></center><center><font color="#9a9a9a"><i>图7 控制信号</i></font></center><br>
图7中给出了各个状态哪些控制信号应该有效,参照图5图6图7可以理清spi整个发送数据的过程。
<font size="4" style="line-height: 40px;" color="red"><strong>四、 verilog描述</strong></font>
接下来使用verilog来描述图6所示的电路,控制信号可根据图7进行描述。
spi发送模块(该模块主要描述控制信号):
<embed src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89035-1.tx…; width="600" height="480" />
计数器电路描述:
<embed src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89036-2.tx…; width="600" height="480" />
移位寄存器电路描述:
<embed src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89037-3.tx…; width="600" height="480" />
触发器电路描述:
<embed src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89038-4.tx…; width="600" height="480" />
仿真激励文件:
<embed src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89039-5.tx…; width="600" height="480" />
使用ISIM仿真结果:
<center><img width="600" src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047181-89034-8.pn…; alt=""></center><center><font color="#9a9a9a"><i>图8 仿真结果</i></font></center><br>
图8中待发送的数据spi_data[7:0]=10101010,由于使用的是SPI3模式(CPOL=1,CPHA=1),此模式下SCK空闲时为1,在SCK第一个时钟沿进行数据发送(即图中SCK下降沿进行数据发送),从图中波形可以看出 ,在cs为低时,mosi被一位一位的送出(高位先输出)。
版权声明:本文为CSDN博主「vegetable_birds123」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43070186/article/details/84257266