1、数据输出通过SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取。完成一位数据传输,输入也使用同样原理。这样,在至少8次时钟信号的改变(上沿和下沿为一次),就可以完成8位数据的传输。要注意的是,SCK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。这样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCK时钟线的控制可以完成对通讯的控制
2、。SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。不同的SPI设备的实现方式不尽相同,主要是数据改变和采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,显得简单高效。在多个从设备的系统中,每个从设备需要独立的使能信号,硬件上比I2C系统要稍微复杂一些。最后,SPI接口的一个缺点:没有指定的流控制,没有应答机制确认是否接收到数据。AT91RM9200的SPI接口主要由4个引脚构成:SPICLK、MOSI、MISO及/SS,其中SPICLK是整个SPI总线的公
3、用时钟,MOSI、MISO作为主机,从机的输入输出的标志,MOSI是主机的输出,从机的输入,MISO是主机的输入,从机的输出。/SS是从机的标志管脚,在互相通信的两个SPI总线的器件,/SS管脚的电平低的是从机,相反/SS管脚的电平高的是主机。在一个SPI通信系统中,必须有主机。SPI总线可以配置成单主单从,单主多从,互为主从。SPI的片选可以扩充选择16个外设,这时PCS输出=NPCS,说NPCS03接4-16译码器,这个译码器是需要外接4-16译码器,译码器的输入为NPCS03,输出用于16个外设的选择。二SPI协议举例SPI是一个环形总线结构,由ss(cs)、sck、sdi、sdo构成,
4、其时序其实很简单,主要是在sck的控制下,两个双向移位寄存器进行数据交换。假设下面的8位寄存器装的是待发送的数据10101010,上升沿发送、下降沿接收、高位先发送。那么第一个上升沿来的时候数据将会是sdo=1;寄存器=0101010x。下降沿到来的时候,sdi上的电平将所存到寄存器中去,那么这时寄存器=0101010sdi,这样在8个时钟脉冲以后,两个寄存器的内容互相交换一次。这样就完成里一个spi时序。举例:假设主机和从机初始化就绪:并且主机的sbuff=0xaa,从机的sbuff=0x55,下面将分步对spi的8个时钟周期的数据情况演示一遍:假设上升沿发送数据这样就完成了两个寄存器8位的
5、交换,上面的上表示上升沿、下表示下降沿,sdi、sdo相对于主机而言的。其中ss引脚作为主机的时候,从机可以把它拉底被动选为从机,作为从机的是时候,可以作为片选脚用。根据以上分析,一个完整的传送周期是16位,即两个字节,因为,首先主机要发送命令过去,然后从机根据主机的命令准备数据,主机在下一个8位时钟周期才把数据读回来。SPI总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟线SCK,一条数据输入线MOSI,一条数据输出线MISO;用于CPU与各种外围器件进行全双工、同步串行通讯。SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程
6、时钟;发送结束中断标志;写冲突保护;总线竞争保护等。下图示出SPI总线工作的四种方式,其中使用的最为广泛的是SPI0和SPI3方式(实线表示):SPI总线四种工作方式模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下
7、降)数据被采样。SPI主模块和与之通信的外设备时钟相位和极性应该一致。SPI总线包括1根串行同步时钟信号线以及2根数据线。SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;SPI主模块和与之通信的外设音时钟相位和极性应该一致。SPI接口时序如图3、图4所示。补充:上文中最后一句话:个人理解这句话有2层意思:其一,主设备SPI时钟和极性的配置应该由外设来决定;其二,二者的配置应该保持一致,即主设备的SDO同从设备的SDO配置一致,主设备的SDI同从设备的SD
8、I配置一致。因为主从设备是在SCLK的控制下,同时发送和接收数据,并通过2个双向移位寄存器来交换数据。工作原理演示如下图:上升沿主机SDO发送数据1,同时从设备SDO发送数据0;紧接着在SCLK的下降沿的时候从设备的SDI接收到了主机发送过来的数据1,同时主机也接收到了从设备发送过来的数据0.三FPGA实现源码LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_arith.ALL;USE ieee.std_logic_unsigned.ALL;ENTITY spi ISPORT(-全局信号NReset: INSTD_LOGIC
9、;-全局复位信号Clk-全局时钟-ResetWdi BUFFER-看门狗的喂狗信号-SPI通讯端口SPINcs INOUT-SPI片选(低有效)SPIClk-SPI时钟SPIMOSI-SPI的主出从入SPIMISO-SPI的主入从出-SPI数据寄存器SPITxdataSTD_LOGIC_VECTOR(15 DOWNTO 0);-待发送数据SPIRxdata-接收数据-SPI状态寄存器SPIStatusSTD_LOGIC_VECTOR(7 DOWNTO 0);-第5位为trdy(发送器准备好),第6位rrdy(接收器准备好)-SPI控制寄存器SPIControl-第0位为mode(模式设置,0为
10、主模式,1为从模式),-第1位为clkpolarity(时钟极性,0时为空闲是低,1为空闲是高),-第2位为clkphasic(时钟相位,0时为前沿检测,1为后沿检测),-第3位为datapriority(数据先后,0时为MSB在前,1为LSB在前),-第4位为start(上升沿开始发送数据),-第7位sso(1时始终置cs为1(无效)SPILength-数据位数寄存器-SPI频率设置寄存器SPISetClkSTD_LOGIC_VECTOR(31 DOWNTO 0)-SPIClk为Clk的SPISetClk分频);END spi;ARCHITECTURE rtl OF spi ISTYPE S
11、tateType IS (S0_Wait,S1_Data,S2_Stop);-状态机定义SIGNALStateIndexStateType;-状态机CntCycleinteger RANGE 0 TO 16383;-位周期计数器CntBitinteger RANGE 0 TO 15;-位数计数器SPITxdataTmp-数据锁存CycleBit-位周期SPIClkCutSTD_LOGIC_VECTOR(31 DOWNTO 0);-生成SPIClk计数器SPIBitCut-SPI的数据位数计数-看门狗计数CntWdiSTD_LOGIC_VECTOR(9 DOWNTO 0);BEGIN-看门狗的喂
12、狗信号的产生-CntWdi = CntWdi + 1 WHEN (ClkEVENT AND Clk = 1-ResetWdi = CntWdi(9);-设置SPI的主从模式,若为主模式则设置SPINcs和SPIClkPROCESS (NReset, Clk)IF(NReset = 0) THEN-复位状态SPINcs = Z;SPIClk SPIMOSI SPIMISO SPIStatus = 01100000SPIRxdata = X0000StateIndex = S0_Wait;SPIClkCut 00000000SPIBitCut = SPIControl(1);IF(SPIContr
13、ol(4) = )THEN-判断起始标志= SPIControl(7);IF(SPIControl(3) = -判断数据MSB还是LSB在前= SPITxdata(CONV_INTEGER(SPILength) - 1);ELSE= SPITxdata(0);END IF;= S1_Data;= StateIndex;WHEN S1_Data =IF(SPIClkCut = ( & SPISetClk(31 DOWNTO 1)-) THEN-SPIClk前沿= NOT SPIClk;= SPIClkCut + 1;IF(SPIControl(2) = -前沿检测= SPIMOSI;= SPIR
14、xdata;SPIRxdata(CONV_INTEGER(SPILength) - SPIBitCut - 1) = SPIMISO;SPIRxdata(SPIBitCut) = (SPISetClk(31 DOWNTO 0) -SPIClk后沿= SPITxdata(CONV_INTEGER(SPILength) - SPIBitCut - 2);IF(SPIBitCut = CONV_INTEGER(SPILength) - 1) THEN= S2_Stop;= SPIBitCut + 1;= SPIClk;WHEN S2_Stop =) THEN= SPINcs;= SPIStatus;WHEN OTHERS =END CASE;-从模式状态END PROCESS;END rtl;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1