定义:SPI(Serial Peripheral Interface)是一种串行外设接口协议,用于在微控制器(MCU)或微处理器之间进行通信。SPI协议通常用于连接主设备(通常是微控制器)与外部从设备(如传感器、存储器芯片、显示器等)之间,以传输数据和控制信息。
SPI通信协议
SPI遵循主从协议,可以一主多从,也可以一主一从,但不能有多个master。提供时钟的为主设备,接收时钟的为从设备slave。SPI接口的读写都是由主设备发起。当处于一主多从模式时,通过各自的片选信号进行管理。
一主一从
一主多从
一个Master SPI能支持多少个从设备一般由主控芯片的硬件设计决定,有多少个片选信号就能支持多少个从设备;当然,想要扩展时可以使用GPIO信号模拟CS信号进而增加从设备的数量,不过使用时要注意时序问题。
SPI默认是全双工的,可以同时发送和接收,且SPI没有定义速度限制,一般的实现通常能达到甚至超过10Mbps
当使用Dual SPI和Quad SPI时,为了增大数据传输速率,SPI是工作在半双工模式的,Dual SPI就是将Single SPI(即普通SPI)的两个数据线改为了同向D0,D1,其传输速率是single SPI的两倍,单个周期传输2bit数据;Quad SPI则是有4个data线,单个周期传输4bit数据。
注意:Dual SPI和Quad SPI通过分时复用理论上也能工作在全双工模式下,但传输效率会低很多
SPI信号线
SPI接口一般使用四条信号线通信: SDI(数据输入),SDO(数据输出),SCK(时钟),CS(片选)
MISO: 主设备输入/从设备输出引脚。该引脚在从模式下发送数据,在主模式下接收数据。
MOSI: 主设备输出/从设备输入引脚。该引脚在主模式下发送数据,在从模式下接收数据。
SCLK:串行时钟信号,由主设备产生。
CS/SS(chip select/Slave select):从设备片选信号,由主设备控制。它的功能是用来作为“片选引脚”,也就是选择指定的从设备,让主设备可以单独地与特定从设备通讯,避免数据线上的冲突。
SPI四种模式
其实就是定义CLK信号哪种状态是有效状态,不像其他协议,SPI对于时钟的有效状态以及上升沿采样还是下降沿采样都是可以配置的
配置是通过以下两个参数也决定的:CPOL时钟极性和CPHA时钟相位,它们分别是Clock Polarity和Clock Phase的缩写。
CPOL时钟极性定义了时钟空闲状态电平:
CPOL=0,表示当SCLK=0时处于空闲态,所以有效状态就是SCLK处于高电平时
CPOL=1,表示当SCLK=1时处于空闲态,所以有效状态就是SCLK处于低电平时
CPHA时钟相位定义数据的采集时间。
CPHA=0,在时钟的第一个跳变沿(上升沿或下降沿)进行数据采样,同时完成数据的发送和接收,在第2个边沿发生数据翻转
注意:因为此时在第一个边沿就要采样,所以如果是第一个周期,那么数据在采样前必须准备好,以便接收端能在第一个时钟前沿采样。
CPHA=1,在时钟的第二个跳变沿(上升沿或下降沿)进行数据采样。,在第1个边沿发生数据翻转
由此引出了SPI的四种工作模式
注意:为了确保SPI主机与SPI从机之间的正确通信,时钟极性和时钟相位以及时钟的设置必须匹配。如果不一致,可能导致数据传输错误或无法通信。如果有多个从设备
,并且它们使用了不同的工作模式,那么主设备
必须在读写不同从设备
时需要重新修改对应从设备的模式
使用最多的模式是SPI0和SPI3
以上内容基本就是SPI总线协议的主要内容,它并没有规定最大传输速率,没有地址方案,没有规定通信应答机制也没有规定流控制规则;只要四根信号线连接正确,SPI模式相同,将CS/SS信号线拉低,即可以直接通信,一次一个字节的传输,读写数据同时操作,这就是SPI。
些通信控制都得通过SPI设备自行实现,SPI并不关心物理接口的电气特性,例如信号的标准电压。
这也是SPI接口的一个缺点:没有指定的流控制,没有应答机制确认是否接收到数据。
SPI通信过程
SPI只有主模式和从模式之分,没有读和写的说法,外设的写操作和读操作是同步完成的。若只进行写操作,主机只需忽略接收到的字节(虚拟数据);反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。也就是说,你发一个数据必然会收到一个数据;你要收一个数据必须也要先发一个数据。
SPI数据通信的流程可以分为以下几步:
- 主设备发起信号,将CS/SS拉低,启动通信。
- 主设备通过发送时钟信号,来告诉从设备进行写数据或者读数据操作(采集时机可能是时钟信号的上升沿(从低到高)或下降沿(从高到低),因为SPI有四种模式),它将立即读取数据线上的信号,这样就得到了一位数据(1bit)。
- 主机(Master)将要发送的数据写到发送数据缓存区(Menory),缓存区经过移位寄存器(缓存长度不一定,看单片机配置,一般有10byte或这8Byte的FIFO),串行移位寄存器通过MOSI信号线将字节一位一位的移出去传送给从机,同时MISO接口接收到的数据经过移位寄存器一位一位的移到接收缓存区。
- 从机(Slave)也将自己的串行移位寄存器(缓存长度不一定,看单片机配置)中的内容通过MISO信号线返回给主机。同时通过MOSI信号线接收主机发送的数据,这样,两个移位寄存器中的内容就被交换。
主机和从机都有一个移位寄存器也是串行移位寄存器,主机移位寄存器数据经过MOSI将数据写入从机的移位寄存器,此时从机的串行移位寄存器的数据也通过MISO传给了主机,实现了两个移位寄存器的数据交换。无论主机还是从机, 发送和接收都是同时进行的,如同一个“环”。
如果主机只对从机进行写操作,主机只需忽略接收的从机数据即可。如果主机要读取从机数据,需要主机发送一个空数据来引发从机发送数据。
具体传输过程举例
例:从W25Q64这个Flash芯片读取存储的数据。该flash芯片充当从设备
由图可知,此SPI工作在mode0,即CPOL=0,CPHA=0
- 传输开始时,主设备单片机在W25Q64的DI(相当于MOSI)发送了一个0x03数据,这个数据对应的是读指令
- 随后,单片机继续发送24bit的内存地址,告知flash要读取哪个内存地址的数据,由于这个地址是由单片机程序确定的,所以不是固定的,可高可低,图中用非确定的方式表示
- 随后就是flash开始给单片机回复24bit地址对应的数据,可以看到回复数据是在W25Q64的DO(相当于MISO)上进行的,由于single SPI是全双工的,此时DI线上仍然可以发送数据给flash
注:仍然要注意,实际上使用SPI进行读操作时读一个字节之前要先发一个字节任意值数据。
具体应用中SPI寄存器能做哪些功能
- 可以设置分频系数,调整时钟频率
- 可以设置CS的有效电平,一般默认低有效
- 可以设置数据帧之间、CS拉低后到CLK开始、CS拉高后到CLK结束等的延迟时间
- 可以设置数据帧的长度
- 可以设置中断触发条件,产生的中断会连接到CPU的中断
- 可以设置中断使能
- 可以设置SPI mode,四种模式
- 可以设置数据格式,先传MSB还是先传LSB,默认时先MSB
- 可以设置single SPI还是Dual、Quad,前提是能支持这些模式
- 可以设置使能信号的行为
- AUTO:正常工作模式,数据传输完成CS恢复到空闲值
- HOLD:数据发送完成后CS保持有效值而非恢复成空闲值
- OFF:关闭CS,CS将一直保持空闲值(空闲值的电平高低取决于SPI处于哪种mode)
- 可以设置RX FIFO是否接收数据
- 可以查询SPI的工作状态,包括
- 中断状态
- 发送接收状态
- 是否空闲
- FIFO中数据表项的数目
- 等等