spi 订阅
SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,越来越多的芯片集成了这种通信协议,比如AT91RM9200。 展开全文
SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,越来越多的芯片集成了这种通信协议,比如AT91RM9200。
信息
应    用
手机、数码、液晶显示器、机顶盒
外文名
Serial Peripheral Interface
缩    写
SPI
中文名
串行外设接口
学    科
通信
特    性
支持全双工
SPI基本协议
SPI总线是一种4线总线,因其硬件功能很强,所以与SPI有关的软件就相当简单,使中央处理器(Central Processing Unit,CPU)有更多的时间处理其他事务。正是因为这种简单易用的特性,越来越多的芯片集成了这种通信协议,比如AT91RM9200。SPI是一种高速、高效率的串行接口技术。通常由一个主模块和一个或多个从模块组成,主模块选择一个从模块进行同步通信,从而完成数据的交换。SPI是一个环形结构,通信时需要至少4根线(事实上在单向传输时3根线也可以) [1]  。SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是MISO(主设备数据输入)、MOSI(主设备数据输出)、SCLK(时钟)、CS(片选)。(1)MISO– Master Input Slave Output,主设备数据输入,从设备数据输出;(2)MOSI– Master Output Slave Input,主设备数据输出,从设备数据输入;(3)SCLK – Serial Clock,时钟信号,由主设备产生;(4)CS – Chip Select,从设备使能信号,由主设备控制。其中,CS是从芯片是否被主芯片选中的控制信号,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),主芯片对此从芯片的操作才有效。这就使在同一条总线上连接多个SPI设备成为可能。接下来就负责通讯的3根线了。通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。这就是SCLK时钟线存在的原因,由SCLK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输。数据输出通过 SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取。完成一位数据传输,输入也使用同样原理。因此,至少需要8次时钟信号的改变(上沿和下沿为一次),才能完成8位数据的传输。SCLK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。这样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCLK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCLK时钟线的控制可以完成对通讯的控制。SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。不同的SPI设备的实现方式不尽相同,主要是数据改变和采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。最后,SPI接口的一个缺点:没有指定的流控制,没有应答机制确认是否接收到数据。SPI的片选可以扩充选择16个外设,这时PCS输出=NPCS,说NPCS0~3接4-16译码器,这个译码器是需要外接4-16译码器,译码器的输入为NPCS0~3,输出用于16个外设的选择。SPI是一个环形总线结构,由ss(cs)、sck、sdi、sdo构成,主要是在sck的控制下,两个双向移位寄存器进行数据交换。假设下面的8位寄存器装的是待发送的数据10101010,上升沿发送、下降沿接收、高位先发送。那么第一个上升沿来的时候 数据将会是sdo=1;寄存器=0101010x。下降沿 合并图册(2张) 到来的时候,sdi上的电平将锁存到寄存器中去,那么这时寄存器=0101010sdi,这样在 8个时钟脉冲以后,两个寄存器的内容互相交换一次。这样就完成了一个spi时序。举例:假设主机和从机初始化就绪:并且主机的sbuff(串行口收发缓冲器)=0xaa,从机的sbuff(串行口收发缓冲器)=0x55,下面将分步对spi的8个时钟周期的数据情况演示一遍:这样就完成了两个寄存器8位的交换,上面的上表示上升沿、下表示下降沿,sdi、sdo相对于主机而言的。其中ss引脚作为主机的时候,从机可以把它拉低被动选为从机,作为从机的时候,可以作为片选脚用。根据以上分析,一个完整的传送周期是16位,即两个字节,因为,首先主机要发送命令过去,然后从机根据主机的命令准备数据,主机在下一个8位时钟周期才把数据读回来。SPI 总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟线SCK,一条数据输出线MOSI,一条数据输入线MISO;用于CPU与各种外围器件进行全双工、同步串行通讯。SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束 中断标志;写冲突保护;总线竞争保护等。下图示出SPI总线工作的四种方式,其中使用的最为广泛的是SPI0和SPI3方式 (实线表示): SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;SPI主模块和与之通信的外设时钟相位和极性应该一致。SPI接口时序如图3、图4所示。 该模块针对用户不同的应用来设计,本质上就是用户的具体业务应用,与SPI-4接口没有直接关系。当应用支持多个端口时,这部分就显得至关重要。下面以支持两个端口的应用来说明用户逻辑的设计技巧。(1)Sink Core的用户逻辑端口为两个时,用户逻辑就需要用两个不同的FIFO根据端口的地址等来分别缓存用户的两个业务数据.同时根据FIFO的情况来发出流控信息给SPI4数据接口,如图1所示。 图1 Sink Core 两个端口的用户逻辑(2) Source Core的用户逻辑当端口为两个时,用户逻辑就需要根据流控信息和两个不同的FffiOffJ情况来做仲裁,谀定哪个用户逻辑FIFO需要发送给SPI4数据接口,如图2所示. 图2 Source Core2个端口的用户逻辑SPI有3种规格,如右图所示为其模型。 3种SPI的处理流程大同小异,使用最多的SPI-4为例来说明SPI的原理。它在发送接口和接收接口都有各自的数据通道和流控状态信息通道,其数据通道和流控状态信息通道是独立的并且是点对点通信。数据是以包的形式发送,根据数据包中的内嵌地址可支持高达256个端口,以下分别说明基本协议及数据通道和流控状态信息的处理过程。SPI时序图详解---SPI接口在模式0下输出第一位数据的时刻。 SPI接口有四种不同的数据传输时序,取决于CPOL和CPHL这两位的组合。图1中表现了这四种时序,时序与CPOL、CPHA的关系也可以从图中看出。CPOL是用来决定SCK时钟信号空闲时的电平,CPOL=0,空闲电平为低电平,CPOL=1时,空闲电平为高电平。CPHA是用来决定采样时刻的,CPHA=0,在每个周期的第一个时钟沿采样,CPHA=1,在每个周期的第二个时钟沿采样 [2]  。SPI:高速同步串行口。是一种标准的四线同步双向串行总线,是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI总线系统是一种同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息。外围设置FLASHRAM、网络控制器、LCD显示驱动器、A/D转换器和MCU等。SPI总线系统可直接与各个厂家生产的多种标准外围器件直接接口,该接口一般使用4条线:串行时钟线(SCLK)、主机输入/从机输出数据线MISO、主机输出/从机输入数据线MOSI和低电平有效的从机选择线SS(有的SPI接口芯片带有中断信号线INT、有的SPI接口芯片没有主机输出/从机输入数据线MOSI)。SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(用于单向传输时,也就是半双工方式)。也是所有基于SPI的设备共有的,它们是SDI(数据输入)、SDO(数据输出)、SCLK(时钟)、CS(片选)。(1)MOSI– SPI总线主机输出/ 从机输入(SPI Bus Master Output/Slave Input);(2)MISO– SPI总线主机输入/ 从机输出(SPI Bus Master Input/Slave Output);(3)SCLK –时钟信号,由主设备产生;(4)CS – 从设备使能信号,由主设备控制(Chip select),有的IC此pin脚叫SS。其中CS是控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效。这就允许在同一总线上连接多个SPI设备成为可能。接下来就负责通讯的3根线了。通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。这就是SCLK时钟线存在的原因,由SCK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输。数据输出通过 SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取。完成一位数据传输,输入也使用同样原理。这样,在至少8次时钟信号的改变(上沿和下沿为一次),就可以完成8位数据的传输。在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,显得简单高效。在多个从设备的系统中,每个从设备需要独立的使能信号,硬件上比I2C系统要稍微复杂一些。在多个从器件的系统中,每个从器件需要独立的使能信号,硬件上比I2C系统要稍微复杂一些。SPI接口在内部硬件实际上是两个简单的移位寄存器,传输的数据为8位,在主器件产生的从器件使能信号和移位脉冲下,按位传输,高位在前,低位在后。如下图所示,在SCLK的下降沿上数据改变,同时一位数据被存入移位寄存器。AT91RM9200的SPI接口主要由4个引脚构成:SPICLK、MOSI、MISO及 NSS,其中SPICLK是整个SPI总线的公用时钟,MOSI、MISO作为主机,从机的输入输出的标志,MOSI是主机的输出,从机的输入,MISO 是主机的输入,从机的输出。NSS是从机的标志管脚,在互相通信的两个SPI总线的器件,NSS管脚的电平低的是从机,相反NSS管脚的电平高的是主机。在一个SPI通信系统中,必须有主机。SPI总线可以配置成单主单从,单主多从,互为主从。SPI的片选可以扩充选择16个外设,这时PCS输出=NPCS,说NPCS0~3接4-16译码器,这个译码器是需要外接4-16译码器,译码器的输入为NPCS0~3,输出用于16个外设的选择。SPI接口的一个缺点:没有指定的流控制,没有应答机制确认是否接收到数据。SPI是一个环形总线结构,由ss(cs)、sck、sdi、sdo构成,其时序其实很简单,主要是在sck的控制下,两个双向移位寄存器进行数据交换。假设下面的8位寄存器装的是待发送的数据10101010,上升沿发送、下降沿接收、高位先发送。那么第一个上升沿来的时候 数据将会是sdo=1;寄存器中的10101010左移一位,后面补入送来的一位未知数x,成了0101010x。下降沿到来的时候,sdi上的电平将锁存到寄存器中去,那么这时寄存器=0101010sdi,这样在 8个时钟脉冲以后,两个寄存器的内容互相交换一次。这样就完成了一个spi时序。上文中最后一句话:SPI主模块和与之通信的外设备时钟相位和极性应该一致。个人理解这句话有2层意思:其一,主设备SPI时钟和极性的配置应该由外设来决定;其二,二者的配置应该保持一致,即主设备的SDO同从设备的SDO配置一致,主设备的SDI同从设备的SDI配置一致。因为主从设备是在SCLK的控制下,同时发送和接收数据,并通过2个双向移位寄存器来交换数据。工作原理演示如下图:上升沿主机SDO发送数据1,同时从设备SDO发送数据0;紧接着在SCLK的下降沿的时候从设备的SDI接收到了主机发送过来的数据1,同时主机也接收到了从设备发送过来的数据0。SPI接口时钟配置心得:在主设备这边配置SPI接口时钟的时候一定要弄清楚从设备的时钟要求,因为主设备这边的时钟极性和相位都是以从设备为基准的。因此在时钟极性的配置上一定要搞清楚从设备是在时钟的上升沿还是下降沿接收数据,是在时钟的下降沿还是上升沿输出数据。但要注意的是,由于主设备的SDO连接从设备的SDI,从设备的SDO连接主设备的SDI,从设备SDI接收的数据是主设备的SDO发送过来的,主设备SDI接收的数据是从设备SDO发送过来的,所以主设备这边SPI时钟极性的配置(即SDO的配置)跟从设备的SDI接收数据的极性是相反的,跟从设备SDO发送数据的极性是相同的。下面这段话是Sychip Wlan8100 Module Spec上说的,充分说明了时钟极性是如何配置的:The 81xx module will always input data bits at the rising edge of the clock,and the host will always output data bits on the falling edge of the clock.意思是:主设备在时钟的下降沿发送数据,从设备在时钟的上升沿接收数据。因此主设备这边SPI时钟极性应该配置为下降沿有效。又如,下面这段话是摘自LCD Driver IC SSD1289:SDI is shifted into 8-bit shift register on every rising edge of SCK in the order of data bit 7,data bit 6 …… data bit 0。意思是:从设备SSD1289在时钟的上升沿接收数据,而且是按照从高位到低位的顺序接收数据的。因此主设备的SPI时钟极性同样应该配置为下降沿有效。时钟极性和相位配置正确后,数据才能够被准确的发送和接收。因此应该对照从设备的SPI接口时序或者Spec文档说明来正确配置主设备的时钟。假设主机和从机初始化就绪:并且主机的sbuff=0xaa,从机的sbuff=0x55,下面将分步对spi的8个时钟周期的数据情况演示一遍:假设上升沿发送数据脉冲主机sbuff 从机sbuff sdi sdo0 10101010 01010101 0 01上 0101010x 1010101x 0 11下 01010100 10101011 0 12上 1010100x 0101011x 1 02下 10101001 01010110 1 03上 0101001x 1010110x 0 13下 01010010 10101101 0 14上 1010010x 0101101x 1 04下 10100101 01011010 1 05上 0100101x 1011010x 0 15下 01001010 10110101 0 16上 1001010x 0110101x 1 06下 10010101 01101010 1 07上 0010101x 1101010x 0 17下 00101010 11010101 0 18上 0101010x 1010101x 1 08下 01010101 10101010 1 0这样就完成了两个寄存器8位的交换,上面的上表示上升沿、下表示下降沿,sdi、sdo相对于主机而言的。其中ss引脚作为主机的时候,从机可以把它拉底被动选为从机,作为从机的是时候,可以作为片选脚用。根据以上分析,一个完整的传送周期是16位,即两个字节,因为,首先主机要发送命令过去,然后从机根据主机的命令准备数据,主机在下一个8位时钟周期才把数据读回来。SPI总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟线SCK,一条数据输入线MISO,一条数据输出线MOSI;用于CPU与各种外围器件进行全双工、同步串行通讯。SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束 中断标志;写冲突保护;总线竞争保护等。下图示出SPI总线工作的四种方式,其中使用的最为广泛的是SPI0和SPI3方式 (实线表示):SPI总线四种工作方式 SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果 CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。SPI主模块和与之通信的外设备时钟相位和极性应该一致。
收起全文
精华内容
参与话题
问答
  • SPI

    千次阅读 多人点赞 2020-01-07 14:29:56
    SPI通信原理 SPI通信模式 数据传输 简介 SPI(Serial Peripheral interface),串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。 SPI,是一种高速的,全双工,同步的通信总线。在芯片的管脚上只...

    目录

    简介

    SPI通信原理

    SPI通信模式

    数据传输


    简介

    SPI(Serial Peripheral interface),串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。
    SPI,是一种高速的,全双工,同步的通信总线。在芯片的管脚上只占用四根线。SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。

    SPI通信原理

    SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,也是所有基于SPI的设备共有的,它们是SDI(数据输入)、SDO(数据输出)、SCLK(时钟)、CS(片选)。
    (1)SDO/MOSI – 主设备数据输出,从设备数据输入;
    (2)SDI/MISO – 主设备数据输入,从设备数据输出;
    (3)SCLK – 时钟信号,由主设备产生;
    (4)CS/SS – 从设备使能信号,由主设备控制。当有多个从设备的时候,因为每个从设备上都有一个片选引脚接入到主设备机中,当我们的主设备和某个从设备通信时将需要将从设备对应的片选引脚电平拉低或者是拉高。

    SPI通信模式

    SPI采用同步方式传输数据,Master 设备会根据将要交换的数据来产生相应的时钟脉冲(Clock Pulse), 时钟脉冲组成了时钟信号(Clock Signal) , 时钟信号通过时钟极性 (CPOL) 和 时钟相位 (CPHA) 控制着两个 SPI 设备间何时数据交换以及何时对接收到的数据进行采样, 来保证数据在两个设备之间是同步传输的。注意:当没有数据交流时,时钟线要么保持高电平要么保持低电平。

    SPI通信有4种不同的模式:
    Mode0:CPOL=0,CPHA=0
    Mode1:CPOL=0,CPHA=1
    Mode2:CPOL=1,CPHA=0
    Mode3:CPOL=1,CPHA=1

    注意:不同的从设备一般在出厂时就配置为某种模式,这是不能改变的;但SPI通信双方必须是工作在同一模式下,所以我们需要对主设备的SPI模式进行配置,通过配置CPOL(时钟极性)和CPHA(时钟相位)来控制主设备的通信模式,

    CPOL时钟极性,表示 SPI 在空闲时,时钟信号是高电平还是低电平。CPHA是用来配置数据采样是在第几个边沿:
    CPOL=0,表示当SCLK=0时处于空闲态,所以有效状态就是SCLK处于高电平时
    CPOL=1,表示当SCLK=1时处于空闲态,所以有效状态就是SCLK处于低电平时
    CPHA=0,表示数据采样是在第1个边沿,数据发送在第2个边沿
    CPHA=1,表示数据采样是在第2个边沿,数据发送在第1个边沿

    例:
    CPOL=0,CPHA=0:此时空闲态时,SCLK处于低电平,数据采样是在第1个边沿,也就是SCLK由低电平到高电平的跳变,所以数据采样是在上升沿,数据发送是在下降沿。

    CPOL=0,CPHA=1:此时空闲态时,SCLK处于低电平,数据发送是在第1个边沿,也就是SCLK由低电平到高电平的跳变,所以数据采样是在下降沿,数据发送是在上升沿。

    CPOL=1,CPHA=0:此时空闲态时,SCLK处于高电平,数据采集是在第1个边沿,也就是SCLK由高电平到低电平的跳变,所以数据采集是在下降沿,数据发送是在上升沿。

    CPOL=1,CPHA=1:此时空闲态时,SCLK处于高电平,数据发送是在第1个边沿,也就是SCLK由高电平到低电平的跳变,所以数据采集是在上升沿,数据发送是在下降沿。

    数据传输

    SPI 设备间的数据传输又被称为数据交换, 因为 SPI 协议规定一个 SPI 设备不能在数据通信过程中仅仅只充当一个 "发送者(Transmitter)" 或者 "接收者(Receiver)".

    在一个SPI时钟周期内,会完成如下操作:
    1)主机通过MOSI线发送1位数据,从机通过该线读取这1位数据;
    2)从机通过MISO线发送1位数据,主机通过该线读取这1位数据。
    这是通过移位寄存器来实现的。如下图所示,主机和从机各有一个移位寄存器,且二者连接成环。随着时钟脉冲,数据按照从高位到低位的方式依次移出主机寄存器和从机寄存器,并且依次移入从机寄存器和主机寄存器。当寄存器中的内容全部移出时,相当于完成了两个寄存器内容的交换。

    一个 Slave 设备要想能够接收到 Master 发过来的控制信号, 必须在此之前能够被 Master 设备进行访问 (Access). 所以, Master 设备必须首先通过 SS/CS pin 对 Slave 设备进行片选, 把想要访问的 Slave 设备选上. 在数据传输的过程中, 每次接收到的数据必须在下一次数据传输之前被采样. 如果之前接收到的数据没有被读取, 那么这些已经接收完成的数据将有可能会被丢弃, 导致 SPI 物理模块最终失效. 因此, 在程序中一般都会在 SPI 传输完数据后, 去读取 SPI 设备里的数据, 即使这些数据(Dummy Data)在我们的程序里是无用的(虽然发送后紧接着的读取是无意义的,但仍然需要从寄存器中读出来)

    展开全文
  • spi

    2017-09-08 01:29:25
    spi协议简介SPI(Serial Peripheral Interface,串行外设接口)是Motorola公司提出的一种同步串行数据传输标准。 SPI 总线在物理上是通过接在外围设备微控制器(PICmicro) 上面的微处理控制单元 (MCU) 上叫作同步串行...

    spi协议简介

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

    SPI 主要应用在 EEPROM, Flash, 实时时钟(RTC), 数模转换器(ADC), 数字信号处理器(DSP) 以及数字信号解码器之间. 它在芯片中只占用四根管脚 (Pin) 用来控制以及数据传输, 节约了芯片的 pin 数目, 同时为 PCB 在布局上节省了空间. 正是出于这种简单易用的特性, 现在越来越多的芯片上都集成了 SPI技术.

    spi接口

    SPI接口经常被称为4线串行总线,以主/从方式工作,数据传输过程由主机初始化。

    • SCLK:串行时钟,用来同步数据传输,由主机输出;
    • MOSI:主机输出从机输入数据线;
    • MISO:主机输入从机输出数据线;
    • CS:片选线,低电平有效,由主机输出。

    特点

    可以同时发出和接收串行数据;可以当作主机或者从机工作;提供频率可编程时钟;发送结束中断标志;写冲突保护;总线竞争保护等。

    优缺点

    SPI接口具有如下优点:

    1) 支持全双工操作;

    2) 操作简单;
    3) 数据传输速率较高。

    同时,它也具有如下缺点:

    1) 需要占用主机较多的口线(每个从机都需要一根片选线);

    2) 只支持单个主机。

    参考博客

    弄懂SPI接口

    spi协议及工作原理分析

    SPI读写总结

    展开全文
  • 【STM32】SPI的基本原理、库函数(SPI一般步骤)

    万次阅读 多人点赞 2018-05-16 14:51:34
    《STM32中文参考手册V10》-第23章 串行外设接口SPI   SPI的基本介绍 SPI的简介 SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口,是Motorola首先在其MC68HCXX系列处理器上定义的...

    STM32F1xx官方资料:

    《STM32中文参考手册V10》-第23章 串行外设接口SPI

     

    SPI的基本介绍

    SPI的简介

    SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口,是Motorola首先在其MC68HCXX系列处理器上定义的。

    SPI接口主要应用在EEPROM、FLASH、实时时钟、AD转换器,还有数字信号处理器和数字信号解码器之间。SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,比如AT91RM9200。

    SPI分为主、从两种模式,一个SPI通讯系统需要包含一个(且只能是一个)主设备,一个或多个从设备。SPI接口的读写操作,都是由主设备发起。当存在多个从设备时,通过各自的片选信号进行管理。

    • 优点:支持全双工通信、通信简单、数据传输速率快;
    • 缺点:没有指定的流控制,没有应答机制确认是否接收到数据,所以跟IIC总线协议比较在数据的可靠性上有一定的缺陷。

    STM32中SPI接口的特点

    • 3线全双工同步传输;
    • 8或16位传输帧格式选择;
    • 主或从操作,支持多主模式;
    • 主模式和从模式下均可以由软件或硬件进行NSS管理:主/从操作模式的动态改变;
    • 可编程的时钟极性和相位;
    • 可编程的数据顺序,MSB在前或LSB在前;
    • 可触发中断的专用发送和接收标志;
    • SPI总线忙状态标志;
    • 支持可靠通信的硬件CRC;
    • 可触发中断的主模式故障、过载以及CRC错误标志;
    • 支持DMA功能的1字节发送和接收缓冲器:产生发送和接受请求。

     

    SPI协议

    SPI引脚说明

    SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。这四根线分别是MISO、MOSI、SCLK、CS,具体的描述见下表:

    SPI各根线的描述
    名称 描述
    MISO 主设备数据输出,从设备数据输入
    MOSI 主设备数据输出,从设备数据输入
    SCLK 时钟信号,主设备产生
    CS 片选信号,主设备控制

    CS:控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(一般默认为低电位),对此芯片的操作才有效,这就允许在同一总线上连接多个SPI设备成为可能。

    也就是说:当有多个从设备的时候,因为每个从设备上都有一个片选引脚接入到主设备机中,当我们的主设备和某个从设备通信时将需要将从设备对应的片选引脚电平拉低。

    MISO/MOSI/SCLK:通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。这就是SCLK时钟线存在的原因,由SCLK提供时钟脉冲,MISO,MOSI则基于此脉冲完成数据传输。数据输出通过MOSI线,数据在时钟上升沿或下降沿时采样,同时也会有返回数据用于接受。完成一位数据传输,输入也使用同样原理。这样,在至少8次时钟信号的改变(上沿和下沿为一次),就可以完成8位数据的传输。

    要注意的是:

    • SCLK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备;
    • 在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,显得简单高效。在多个从设备的系统中,每个从设备需要独立的使能信号,硬件上比I2C系统要稍微复杂一些。

    SPI通讯模式

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

    SPI通讯模式
    模式 CPOL(时钟极性) CPHA(时钟相位)
    MODE0 0 0
    MODE1 0 1
    MODE2 1 0
    MODE3 1 1

    时钟极性CPOL是用来配置SCLK的电平出于哪种状态时是空闲态或者有效态,时钟相位CPHA是用来配置数据采样是在第几个边沿:

    • CPOL=0,表示当SCLK=0时处于空闲态,所以有效状态就是SCLK处于高电平时;
    • CPOL=1,表示当SCLK=1时处于空闲态,所以有效状态就是SCLK处于低电平时;
    • CPHA=0,表示数据采样是在第1个边沿,数据发送在第2个边沿;
    • CPHA=1,表示数据采样是在第2个边沿,数据发送在第1个边沿。

    具体四种模式的时序图如下:

    对于SPI的四种通讯模式,总结起来,就是:

    • CPOL=0,CPHA=0:此时空闲态时,SCLK处于低电平,数据采样是在第1个边沿,也就是SCLK由低电平到高电平的跳变,所以数据采样是在上升沿;
    • CPOL=0,CPHA=1:此时空闲态时,SCLK处于低电平,数据发送是在第1个边沿,也就是SCLK由低电平到高电平的跳变,所以数据采样是在下降沿;
    • CPOL=1,CPHA=0:此时空闲态时,SCLK处于高电平,数据采集是在第1个边沿,也就是SCLK由高电平到低电平的跳变,所以数据采集是在下降沿;
    • CPOL=1,CPHA=1:此时空闲态时,SCLK处于高电平,数据发送是在第1个边沿,也就是SCLK由高电平到低电平的跳变,所以数据采集是在上升沿。

    SPI内部工作机制

    下面对照一个SPI单主机与单从机连接图,理解其内部工作机制:

    • 硬件上为4根线;
    • 主机和从机都有一个串行移位寄存器,主机通过向它的SPI串行寄存器写入一个字节来发起一次传输;
    • 串行移位寄存器通过MOSI信号线将字节传送给从机,同时从机也将自己的串行移位寄存器中的内容通过MISO信号线返回给主机。这样,两个移位寄存器中的内容就被交换;
    • 外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。

    也就是说:SPI是一个环形总线结构,由CS、SCLK、MISO、MOSI构成,其时序其实很简单,主要是在SCLK的控制下,数据按照从高位到低位的方式依次移出主机寄存器和从机寄存器,并且依次移入从机寄存器和主机寄存器。当寄存器中的内容全部移出时,相当于完成了两个寄存器内容的交换。

    假设主机的8位寄存器装的是待发送的数据10101010,上升沿发送、下降沿接收、高位先发送。那么第一个上升沿来的时候,主机将会通过MOSI信号线传输给从机最高位1,自身寄存器变成0101010x。同时,MISO信号线会从从机处返回一个数据给主机,那么这时寄存器为0101010MISO,这样在 8个时钟脉冲以后,两个寄存器的内容互相交换一次。这样就完成里一个SPI时序。 

    这个时候就会有一个疑问,或者说产生一个必然了:

    为什么主机发送一个数据给从机,从机就同时通过MISO返回的一个数据给主机呢?

    解释:主机和从机的发送数据是同时完成的,两者的接收数据也是同时完成的。也就是说,当上升沿主机发送数据的时候,从机也发送了数据。

    所以为了保证主从机正确通信,应使得它们的SPI具有相同的时钟极性和时钟相位。

     

    STM32的SPI接口

    SPI可分为主、从两种模式,并且支持全双工模式,所以这也就导致STM32的SPI接口比较复杂。比如:配置SPI为主模式、配置SPI为从模式、配置SPI为单工通信、配置SPI为双工通信等等。这里的内容就非常庞大,涉及到的寄存器的位也比较多,所以就不介绍太多,想要了解更多可以去查看STM32F1xx官方资料的第23章节。

    SPI接口的框图

    SPI引脚

    STM32的SPI接口通过4个引脚与外部器件相连,与标准的SPI协议是一致的:

    • MISO:主设备输入/从设备输出引脚。该引脚在从模式下发送数据,在主模式下接收数据;
    • MOSI:主设备输出/从设备输入引脚。该引脚在主模式下发送数据,在从模式下接收数据;
    • SCK:串口时钟,作为主设备的输入,从设备的输入;
    • NSS:从设备选择。这是一个可选的引脚,用来选择主/从设备。它的功能是用来作为“片选引脚”,让主设备可以单独地与特定从设备通讯,避免数据线上的冲突。

    从选择(NSS)脚管理

    有2种NSS模式:

    • 软件NSS模式:可以通过设置SPI_CR1寄存器的SSM位来使能这种模式。在这种模式下NSS引脚可以用作它用,而内部NSS信号电平可以通过写SPI_CR1的SSI位来驱动;
    • 硬件NSS模式,分两种情况:
    1. NSS输出被使能:当STM32F10xxx工作为主SPI,并且NSS输出已经通过SPI_CR2寄存器的SSOE位使能,这时NSS引脚被拉低,所有NSS引脚与这个主SPI的NSS引脚相连并配置为硬件NSS的SPI设备,将自动变成从SPI设备。 当一个SPI设备需要发送广播数据,它必须拉低NSS信号,以通知所有其它的设备它是主设备;如果它不能拉低NSS,这意味着总线上有另外一个主设备在通信,这时将产生一个硬件失败错误;
    2. NSS输出被关闭:允许操作于多主环境。

    数据帧格式

    • 根据SPI_CR1寄存器中的LSBFIRST位,输出数据位时可以左对齐(MSB对齐标准)也可以右对齐(LSB对齐标准)。
    • 根据SPI_CR1寄存器的DFF位,每个数据帧可以是8位或是16位。所选择的数据帧格式对发送和/或接收都有效。

    状态标志

    应用程序通过3个状态标志可以完全监控SPI总线的状态:

    • 发送缓冲器空闲标志(TXE)

    此标志为1时表明发送缓冲器为空,可以写下一个待发送的数据进入缓冲器中。当写入SPI_DR时,TXE标志被清除。

    • 接收缓冲器非空(RXNE)

    此标志为1时表明在接收缓冲器中包含有效的接收数据。读SPI数据寄存器可以清除此标志。

    • 忙(Busy)标志

    BSY标志由硬件设置与清除(写入此位无效果),此标志表明SPI通信层的状态。

    当它被设置为1时,表明SPI正忙于通信,但有一个例外:在主模式的双向接收模式下(MSTR=1、BDM=1并且BDOE=0),在接收期间BSY标志保持为低。

    在软件要关闭SPI模块并进入停机模式(或关闭设备时钟)之前,可以使用BSY标志检测传输是否结束,这样可以避免破坏最后一次传输,因此需要严格按照下述过程执行。

    SPI中断

     

    STM32的SPI引脚

    SPI引脚位置

    外设的GPIO配置

     

    SPI相关配置库函数

    • 1个初始化函数
    void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);

    作用:初始化SPI的相关参数,比如方向(全双工)、主从模式、数据大小、CPOL、CPHA、片选软件模式、预分频系数等。

    • 3个使能函数
    void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);
    void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
    void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState);

    作用:使能SPI接口;使能SPI中断;使能SPI的DMA功能。

    • 2个数据传输函数
    void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
    uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);

    作用:分别用于SPI传输数据、接收数据。

    • 4个状态位函数
    FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
    void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
    ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
    void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);

    作用:前两者用于获得和清除SPI的各种状态位;后两者则针对SPI的中断标志位。

     

    SPI一般步骤

    实验目标:利用SPI2进行初始化等操作。

    • 配置相关引脚的复用功能,使能SPIx时钟。调用函数:void GPIO_Init();
    • 初始化SPIx,设置SPIx工作模式。调用函数:void SPI_Init();
    • 使能SPIx。调用函数:void SPI_Cmd();
    • SPI传输数据。调用函数:void SPI_I2S_SendData();uint16_t SPI_I2S_ReceiveData();
    • 查看SPI传输状态。调用函数:SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE)。

    下面按照这个一般步骤来进行一个简单的SPI程序:

    void SPI2_Init(void)
    {
     	GPIO_InitTypeDef GPIO_InitStructure;
      SPI_InitTypeDef  SPI_InitStructure;
    
    	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能 
    	RCC_APB1PeriphClockCmd(	RCC_APB1Periph_SPI2,  ENABLE );//SPI2时钟使能 	
     
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //PB13/14/15复用推挽输出 
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB
    
     	GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);  //PB13/14/15上拉
    
    	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
    	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		//设置SPI工作模式:设置为主SPI
    	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//设置SPI的数据大小:SPI发送接收8位帧结构
    	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;		//串行同步时钟的空闲状态为高电平
    	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;	//串行同步时钟的第二个跳变沿(上升或下降)数据被采样
    	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
    	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;		//定义波特率预分频的值:波特率预分频值为256
    	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
    	SPI_InitStructure.SPI_CRCPolynomial = 7;	//CRC值计算的多项式
    	SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
     
    	SPI_Cmd(SPI2, ENABLE); //使能SPI外设
    	
    	SPI2_ReadWriteByte(0xff);//启动传输		 
     
    
    }   
    //SPI 速度设置函数
    //SpeedSet:
    //SPI_BaudRatePrescaler_2   2分频   
    //SPI_BaudRatePrescaler_8   8分频   
    //SPI_BaudRatePrescaler_16  16分频  
    //SPI_BaudRatePrescaler_256 256分频 
      
    void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
    {
      assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
    	SPI2->CR1&=0XFFC7;
    	SPI2->CR1|=SPI_BaudRatePrescaler;	//设置SPI2速度 
    	SPI_Cmd(SPI2,ENABLE); 
    
    } 
    
    //SPIx 读写一个字节
    //TxData:要写入的字节
    //返回值:读取到的字节
    u8 SPI2_ReadWriteByte(u8 TxData)
    {		
    	u8 retry=0;				 	
    	while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
    		{
    		retry++;
    		if(retry>200)return 0;
    		}			  
    	SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据
    	retry=0;
    
    	while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
    		{
    		retry++;
    		if(retry>200)return 0;
    		}	  						    
    	return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据					    
    }

     

    展开全文
  • SPI协议详解

    万次阅读 多人点赞 2018-09-19 15:15:27
    1.SPI协议简介 1.1.SPI协议概括  SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM,FLASH,实时时钟,...

    1.SPI协议简介

    1.1.SPI协议概括

      SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,比如AT91RM9200.

    SPI主从模式硬件连接如下图

      SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是SDI(数据输入),SDO(数据输出),SCK(时钟),CS(片选)。

    • SDO     – 主设备数据输出,从设备数据输入 对应MOSI master output slave input
    • SDI      – 主设备数据输入,从设备数据输出  对应MISO master input slave output
    • SCLK   – 时钟信号,由主设备产生
    • CS        – 从设备使能信号,由主设备控制

      CS: 其中CS是控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效,这就允许在同一总线上连接多个SPI设备成为可能。

      SDI/SDO/SCLK: 通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。这就是SCK时钟线存在的原因,由SCK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输。数据输出通过 SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取。完成一位数据传输,输入也使用同样原理。这样,在至少8次时钟信号的改变(上沿和下沿为一次),就可以完成8位数据的传输。

      要注意的是,SCK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。

    这样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据,也就是说,主设备通过对SCK时钟线的控制可以完成对通讯的控制。SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。不同的SPI设备的实现方式不尽相同,主要是数据改变和采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。

    在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,显得简单高效。在多个从设备的系统中,每个从设备需要独立的使能信号,硬件上比I2C系统要稍微复杂一些。

    最后,SPI接口的一个缺点:没有指定的流控制,没有应答机制确认是否接收到数据

    AT91RM9200的SPI接口主要由4个引脚构成:SPICLK、MOSI、MISO及 /SS,其中SPICLK是整个SPI总线的公用时钟,MOSI、MISO作为主机,从机的输入输出的标志,MOSI是主机的输出,从机的输入,MISO 是主机的输入,从机的输出。/SS是从机的标志管脚,在互相通信的两个SPI总线的器件,/SS管脚的电平低的是从机,相反/SS管脚的电平高的是主机。在一个SPI通信系统中,必须有主机。SPI总线可以配置成单主单从,单主多从,互为主从。

    SPI的片选可以扩充选择16个外设,这时PCS输出=NPCS,说NPCS0~3接4-16译码器,这个译码器是需要外接4-16译码器,译码器的输入为NPCS0~3,输出用于16个外设的选择。

    2.协议举例

    如下图,是SPI的简单收发时序图。

    SPI是一个环形总线结构,由ss(cs)、sck、sdi、sdo构成,其时序其实很简单,主要是在sck的控制下,两个双向移位寄存器进行数据交换。
           假设下面的8位寄存器装的是待发送的数据10101010,上升沿发送、下降沿接收、高位先发送。
           那么第一个上升沿来的时候 数据将会是sdo=1;寄存器=0101010x。下降沿到来的时候,sdi上的电平将锁存到寄存器中去,那么这时寄存器=0101010sdi,这样在 8个时钟脉冲以后,两个寄存器的内容互相交换一次。这样就完成里一个spi时序。 

    举例: 
           假设主机和从机初始化就绪:并且主机的sbuff=0xaa,从机的sbuff=0x55,下面将分步对spi的8个时钟周期的数据情况演示一遍:假设上升沿发送数据

    这样就完成了两个寄存器8位的交换,上面的上表示上升沿、下表示下降沿,sdi、sdo相对于主机而言的。其中ss引脚作为主机的时候,从机可以把它拉底被动选为从机,作为从机的是时候,可以作为片选脚用。根据以上分析,一个完整的传送周期是16位,即两个字节,因为,首先主机要发送命令过去,然后从机根据主机的命令准备数据,主机在下一个8位时钟周期才把数据读回来。

         

      SPI 总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟线SCK,一条数据输入线MOSI,一条数据输出线MISO;用于CPU与各种外围器件进行全双工、同步串行通讯。SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束 中断标志;写冲突保护;总线竞争保护等。下图示出SPI总线工作的四种方式,其中使用的最为广泛的是SPI0和SPI3方式 (实线表示):                  

                                                        

    3. SPI总线四种工作方式

    SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。

           时序详解:

      CPOL:时钟极性选择,为0时SPI总线空闲为低电平,为1时SPI总线空闲为高电平

      CPHA:时钟相位选择,为0时在SCK第一个跳变沿采样,为1时在SCK第二个跳变沿采样

      工作方式1:

      当CPHA=0、CPOL=0时SPI总线工作在方式1。MISO引脚上的数据在第一个SPSCK沿跳变之前已经上线了,而为了保证正确传输,MOSI引脚的MSB位必须与SPSCK的第一个边沿同步,在SPI传输过程中,首先将数据上线,然后在同步时钟信号的上升沿时,SPI的接收方捕捉位信号,在时钟信号的一个周期结束时(下降沿),下一位数据信号上线,再重复上述过程,直到一个字节的8位信号传输结束。

      工作方式2:

      当CPHA=0、CPOL=1时SPI总线工作在方式2。与前者唯一不同之处只是在同步时钟信号的下降沿时捕捉位信号,上升沿时下一位数据上线。

      工作方式3:

      当CPHA=1、CPOL=0时SPI总线工作在方式3。MISO引脚和MOSI引脚上的数据的MSB位必须与SPSCK的第一个边沿同步,在SPI传输过程中,在同步时钟信号周期开始时(上升沿)数据上线,然后在同步时钟信号的下降沿时,SPI的接收方捕捉位信号,在时钟信号的一个周期结束时(上升沿),下一位数据信号上线,再重复上述过程,直到一个字节的8位信号传输结束。

      工作方式4:

      当CPHA=1、CPOL=1时SPI总线工作在方式4。与前者唯一不同之处只是在同步时钟信号的上升沿时捕捉位信号,下降沿时下一位数据上线。

    4种工作模式波形时序如下图:

    åç§å·¥ä½æ¹å¼æ¶åº

    4.协议心得

    SPI接口时钟配置心得:

      在主设备这边配置SPI接口时钟的时候一定要弄清楚从设备的时钟要求,因为主设备这边的时钟极性和相位都是以从设备为基准的。因此在时钟极性的配置上一定要搞清楚从设备是在时钟的上升沿还是下降沿接收数据,是在时钟的下降沿还是上升沿输出数据。但要注意的是,由于主设备的SDO连接从设备的SDI,从设备的SDO连接主设备的SDI,从设备SDI接收的数据是主设备的SDO发送过来的,主设备SDI接收的数据是从设备SDO发送过来的,所以主设备这边SPI时钟极性的配置(即SDO的配置)跟从设备的SDI接收数据的极性是相反的,跟从设备SDO发送数据的极性是相同的。下面这段话是Sychip Wlan8100 Module Spec上说的,充分说明了时钟极性是如何配置的:

    The 81xx module will always input data bits at the rising edge of the clock, and the host will always output data bits on the falling edge of the clock.

    意思是:主设备在时钟的下降沿发送数据,从设备在时钟的上升沿接收数据。因此主设备这边SPI时钟极性应该配置为下降沿有效。

    又如,下面这段话是摘自LCD Driver IC SSD1289:

    SDI is shifted into 8-bit shift register on every rising edge of SCK in the order of data bit 7, data bit 6 …… data bit 0.

    意思是:从设备SSD1289在时钟的上升沿接收数据,而且是按照从高位到地位的顺序接收数据的。因此主设备的SPI时钟极性同样应该配置为下降沿有效。

    时钟极性和相位配置正确后,数据才能够被准确的发送和接收, 因此应该对照从设备的SPI接口时序或者Spec文档说明来正确配置主设备的时钟。

    5.SPI协议软件模拟

    5.1.单片机软件模拟SPI接口—加深理解SPI总线协议

            现以 AT89C205l单片机模拟SPI总线操作串行EEPROM 93CA6为例,如图1所示,介绍利用单片机的I/O口通过软件模拟SPI总线的实现方法。在这里,仅介绍读命令的时序和应用子程序。 

    5.2.93C46存储器SPI总线的工作原理

              93CA6作为从设备,其SPI接口使用4条I/O口线:串行时钟线(SK)、输出数据线DO、输入数据线DI和高电平有效的从机选择线CS。其数据的传输格式是高位(MSB)在前,低位(LsB)在后。93C46的SPI总线接口读命令时序如图2所示。 

    5.3.软件模拟SPI接口的实现方法 

              对于不带SPI串行总线接口的AT89C2051单片 机来说,可以使用软件来模拟SPI的操作,图1所示 为AT89C2051单片机与串行EEPROM 93C46的硬件 连接图,其中,P1.0模拟SPI主设备的数据输出端 SDO,P1.2模拟SPI的时钟输出端SCK,P1.3模拟 SPI的从机选择端SCS,P1.1模拟SPI的数据输入 SDI。
             上电复位后首先先将P1.2(SCK)的初始状态设置为0(空闲状态)。
             读操作:AT89C2051首先通过P1.0口发送1位起始位(1),2位操作码(10),6位被读的数据地址(A5A4A3A2A1A0),然后通过P1.1口读1位空位(0),之后再读l6位数据(高位在前)。
             写操作:AT89C2051首先通过P1.0口发送1位起始位(1),2位操作码(01),6位被写的数据地址(A5A4A3A2A1A0),之后通过P1.0口发送被写的l6位数据(高位在前),写操作之前要发送写允许命令,写之后要发送写禁止命令。
             写允许操作(WEN)):写操作首先发送1位起始位(1),2位操作码(00),6位数据(11XXXX)。              

             写禁止操作(WDS)):写操作首先发送1位起始位(1),2位操作码(00),6位数据(00XXXX)。

            下面介绍用C51模拟SPI的子程序。

    /*例子1*/
    //首先定义好I/O口
    sbit SDO=P1^0;
    sbit SDI=P1^1;
    sbit SCK=P1^ 2;
    sbit SCS=P1^3;
    sbit ACC_7= ACC^7;
    unsigned int SpiRead(unsigned char add)
    {
        unsigned char i;
        unsigned int datal6;
        add&=0x3f;/*6位地址*/
        add |=0x80;/*读操作码l0*/
        SDO=1;/*发送1为起始位*/
        SCK=0;
        SCK=1;
        for(i=0;<8;i++)/*发送操作码和地址*/
        {
            if(add&0x80==1)
                SDO=1;
            else 
                SDO=0;
            SCK=0;/*从设备上升沿接收数据*/
            SCK=1;
            add<<= 1;
        }
        SCK=1;/*从设备时钟线下降沿后发送数据,空读1位数据*/
        SCK=0;
        datal6<<= 1;/*读16位数据*/
        for(i=0;<16;i++)
        {
            SCK= 1;
            _nop_();
            if(SDI==1)
                datal6|=0x01;
            SCK =0;
            datal6< < =1;
        }
        return datal6;
    }
        
    /*例子2*/
        #define SS      252                     //定义SS所对应的GPIO接口编号  
        #define SCLK    253                     //定义SCLK所对应的GPIO接口编号  
        #define MOSI    254                     //定义SCLK所对应的GPIO接口编号  
        #define MISO    255                     //定义MISO所对应的GPIO接口编号  
        #define OUTP    1                       //表示GPIO接口方向为输出  
        #define INP 0                           //表示GPIO接口方向为输入  
        
        /* SPI端口初始化 */  
        void spi_init()  
        {  
            set_gpio_direction(SS, OUTP);  
            set_gpio_direction(SCLK, OUTP);  
            set_gpio_direction(MOSI, OUTP);  
            set_gpio_direction(MISO, INP);  
            set_gpio_value(SCLK, 0);//CPOL=0 
            set_gpio_value(MOSI, 0);
        }  
        /*  
        从设备使能  
        enable:为1时,使能信号有效,SS低电平  
        为0时,使能信号无效,SS高电平  
        */  
        void ss_enable(int enable)  
        {  
            if (enable)  
                set_gpio_value(SS, 0);//SS低电平,从设备使能有效  
            else  
                set_gpio_value(SS, 1);//SS高电平,从设备使能无效  
        }  
        
        /* SPI字节写 */  
        void spi_write_byte(unsigned char b)  
        {  
            int i;  
            for (i=7; i>=0; i--) {  
                set_gpio_value(SCLK, 0);  
                set_gpio_value(MOSI, b&(1<<i));//从高位7到低位0进行串行写入  
                delay();//延时  
                set_gpio_value(SCLK, 1);// CPHA=1,在时钟的第一个跳变沿采样  
                delay();      
            }  
        }  
        /* SPI字节读 */  
        unsigned char spi_read_byte()  
        {  
            int i;  
            unsigned char r = 0;  
            for (i=0; i<8; i++) {  
                set_gpio_value(SCLK, 0);  
                delay();//延时  
                set_gpio_value(SCLK, 1);// CPHA=1,在时钟的第一个跳变沿采样  
                r = (r <<1) | get_gpio_value(MISO);//从高位7到低位0进行串行读出  
                delay();  
            }  
        }  
        /*  
            SPI写操作  
            buf:写缓冲区  
            len:写入字节的长度  
        */  
        void spi_write (unsigned char* buf, int len)  
        {  
            int i;  
            spi_init();//初始化GPIO接口  
            ss_enable(1);//从设备使能有效,通信开始  
            delay();//延时  
            //写入数据  
            for (i=0; i<len; i++)
                spi_write_byte(buf[i]);
            delay();
            ss_enable(0);//从设备使能无效,通信结束  
        }  
        /*  
        SPI读操作  
        buf:读缓冲区  
        len:读入字节的长度  
        */  
        void spi_read(unsigned char* buf, int len)  
        {  
            int i;  
            spi_init();//初始化GPIO接口  
            ss_enable(1);//从设备使能有效,通信开始  
            delay();//延时  
            //读入数据
            for (i=0; i<len; i++)
                buf[i] = spi_read_byte();
            delay();
            ss_enable(0);//从设备使能无效,通信结束  
        }

      对于不同的串行接口外围芯片,它们的时钟时序是不同的。上述子程序是针对在SCK的上升沿输入(接收)数据和在下降沿输出(发送)数据的器件。这些子程序也适用于在串行时钟)的上升沿输入和下降沿输出的其它各种串行外围接口芯片,只要在程序中改变P1.2(SCK)的输出电平顺序进行相应调整即可。

     

    6. Linux下的SPI源码

    链接:https://pan.baidu.com/s/1Jm_gDxj-to965ZH3I16dug 密码:c9ki

    加我微信,拉进微信技术讨论群

         喜欢的可以关注微信公众号-嵌入式Linux

     

    展开全文
  • 【原创】【SPISPI Flash介绍

    万次阅读 多人点赞 2018-03-25 22:28:30
    一、这是个什么玩意首先它是个Flash...那么严格的来说SPI Flash是一种使用SPI通信的Flash,即,可能指NOR也可能是NAND。但现在大部分情况默认下人们说的SPI Flash指的是SPI NorFlash。早期Norflash的接口是parallel...
  • STM32 SPI详解

    万次阅读 多人点赞 2016-07-17 22:28:23
    1、 SPI简介 SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号...
  • 基本概念: CPOL CPOL:Clock Polarity,时钟的极性。 时钟的极性是什么概念呢? 通信的整个过程分为空闲时刻和通信时刻; 如果SCLK在数据发送之前和之后的空闲状态是高电平,那么就是CPOL=1; ...
  • spi 01-spi 是什么?入门使用 spi 02-spi 的实战解决 slf4j 包冲突问题 spi 03-spi jdk 实现源码解析 spi 04-spi dubbo 实现源码解析 spi 05-dubbo adaptive extension 自适应拓展 spi 06-自己从零手写实现 SPI 框架...
  • SPI通信协议基础

    千次阅读 2020-08-12 09:01:17
    当您将微控制器连接到传感器,显示器或其他模块时,您是否考虑过这两种设备如何相互通信?他们到底在说什么?他们如何互相了解?
  • SPI接口详细介绍

    万次阅读 多人点赞 2018-10-16 20:02:45
    SPI = Serial Peripheral Interface,是串行外围设备接口,是一种高速,全双工,同步的通信总线。常规只占用四根线,节约了芯片管脚,PCB的布局省空间。现在越来越多的芯片集成了这种通信协议,常见的有EEPROM、...
  • 标准SPI、DUAL SPI、Quad SPI

    千次阅读 2019-05-22 16:57:06
    1. 标准SPI 标准SPI通常就称SPI,它是一种串行外设接口规范,有4根引脚信号:clk , cs, mosi, miso 2. Dual SPI 它只是针对SPI Flash而言,不是针对所有SPI外设。对于SPI Flash,全双工并不常用,因此扩展了mosi...
  • 关注、星标公众号,不错过精彩内容整理:黄工来源:亚德诺半导体提问:能否用MCU访问非标准SPI接口?答案:可以,但可能需要做一些额外的努力。当前许多精密模数转换器(ADC)具有串行外设接...
  • 标准SPI通常就称SPI,它是一种串行外设接口规范,有4根引脚信号:clk , cs, mosi, miso 2. Dual SPI 它只是针对SPI Flash而言,不是针对所有SPI外设。对于SPI Flash,全双工并不常用,因此扩展了mosi和mi...
  • while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){} //等待接收完一个byte val=SPI_I2S_ReceiveData(SPI1); GPIO_SetBits(GPIOA,GPIO_Pin_4); return val+val1; //返回通过SPIx...
  • java SPI 04-spi dubbo 实现源码解析

    万次阅读 2020-06-18 22:52:42
    spi 01-spi 是什么?入门使用 spi 02-spi 的实战解决 slf4j 包冲突问题 spi 03-spi jdk 实现源码解析 spi 04-spi dubbo 实现源码解析 spi 05-dubbo adaptive extension 自适应拓展 spi 06-自己从零手写实现 SPI 框架...
  • 如何理解Stand SPI Dual SPI 和Quad SPI

    千次阅读 2019-04-18 10:37:20
    如何理解Stand SPI Dual SPI 和Quad SPI 1.首先看一下接口 Standard SPI: CLK, /CS, DI, DO, /WP, /Hold 这是全双工模式,输入和输出可以同时进行(mosi, miso分别对应的是DI和DO) Dual SPI: CLK, /CS, IO0, IO1, /WP...
  • 阿里面试真题:Dubbo的SPI机制

    千次阅读 多人点赞 2020-08-27 11:33:37
    被问懵逼了

空空如也

1 2 3 4 5 ... 20
收藏数 33,606
精华内容 13,442
关键字:

spi