SPI基础概念

Posted Naisu Xu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPI基础概念相关的知识,希望对你有一定的参考价值。

目的

SPI(Serial Perripheral Interface)是一种非常常用的全双工接口,这个接口在非常简单的机制下达到了比较高的通讯速度。比它通讯速度更高的常见的要不是并口,要不是ETH、USB这类复杂的通讯接口。使用SPI需要了解一些基础概念,并能够在此基础上看懂时序逻辑。这篇文章将对相关内容做个说明。

SPI还有升级的类型 DSPI(Dual SPI)和 QSPI(Quad SPI),这两种接口拥有更快的通讯速度,代价分别是失去全双工特性和增加额外通讯线。这篇文章不对此进行介绍。

物理接线

SPI是主从方式通讯的,在使用时主要有下面一些接线方式:

可以看到SPI主要涉及的信号线为四条,分别如下:

  • SCLK 时钟信号;
  • MOSI 主机数据输出、从机数据接收;
  • MISO 主机数据接收、从机数据输出;
  • NSS 片选信号,低电平表示选中;
    主机在要通讯时拉低对应从机的NSS引脚来选中该从机;

SPI通讯中主机只能有一个,从机可以有多个。在一主一从的时候从机的NSS引脚可以直接接地,表示该从机一直被选中。

SPI在一主多从的时候还有一种菊花链连接方式,上图中没有画出来。主要特点是所有从机同时选中,从主机开始传输数据到第一个从机,第一个从机的数据输出接到第二个从机的数据输入,依次往后传输。

极性和相位

在解读SPI时序逻辑前需要先了解下SPI极性(CPOL)和相位(CPHA)的概念。CPOL指的是SCLK总线在不进行通讯时的电平,CPHA指在一个时钟周期中采样是发生在第一个边缘还是第二个边缘。根据极性和相位的不同组合SPI有四种工作模式,可以查看下面的图示:

虽然有四种模式,但最重要的就一点,采样是在一个周期中间采样的Mode 0Mode 3 都是上升沿采样, Mode 1Mode 2 都是下降沿采样。很多作为SPI从机使用的芯片都支持两种模式,要不支持0和3,要不支持1和2。

信号时序

起止信号 —— NSS

在不传输数据时NSS通常为高电平状态。数据传输通常以NSS信号拉低开始,一般再拉低半个周期后开始输出时钟信号同时传输数据,完成传输后拉高NSS。通常这个也被叫做摩托罗拉(Motorola)的SPI协议。

还有一种不太一样的,NSS平常为低,在数据传输前NSS保持一段时间高电平然后拉低,接着开始传输数据。这个是德州仪器(TI)的协议,也被称为SSI协议。

数据读写 —— SCLK、MOSI、MISO

SPI是一种很有意思的总线,它的收和发是可以同时进行的,比如上一节的图中可以看到MOSI传输数据的同时MISO也在传输数据。

作为主机来说不管是收数据还是发数据通常都没啥问题,而从机就有问题了——什么时候可以读数据?什么时候要发数据?这个问题就要扯上SCLK了。这也就是前面讲的极性和相位的问题。

读写操作
通常SPI数据读写都是以八个或十六个周期为一组进行,相当于读写一个或两个字节。可以多组连续读写,NSS只在最开始和结束的时候变化。

一般通过库函数作为主机进行SPI通讯时不用手动操作SCLK信号,直接对外写数据即可,SPI控制器会自动操作SCLK、MOSI等信号线。所以常见的读写函数都是下面这种样子的:
uint8_t SPI_Write_Read(uint8_t *Data)
uint16_t SPI_Write_Read(uint16_t *Data)
bool SPI_Write_Read(uint8_t *TxData, uint8_t *RxData, size_t Size)
bool SPI_Write_Read(uint16_t *TxData, uint16_t *RxData, size_t Size)

通常这些情况下你如果只是想要读数据,操作的时候也是需要依靠写入数据来发出时钟信号的,通常写入什么都行,只要长度和你需要读取的数据长度对的上就行。

读写时序
一般来说作为SPI主机与SPI从机进行通讯,读写的时候并不是同步的,想要从从机读取某些数据需要先写入读取动作的指令和参数等,而从机会在接到指令和参数后的一定周期后返回数据。比如下面这样:

上面请求和返回数据时间刚好相差八个周期。当然也有可能是下面这样的:

上面请求和返回数据时间相差十六个周期。

其实SPI读写中各种情况组合是非常多的,具体的还需要看你要操作的从机设备的文档中对时序的描述。

总结

对SPI的操作主要就是要了解极性相位以及时序等内容,剩下的使用来说还是很简单的,无非是查一查从机的通讯文档相关的通讯逻辑而已。

以上是关于SPI基础概念的主要内容,如果未能解决你的问题,请参考以下文章

Android Fragments 基础知识:为啥?这在概念上是错误的吗?

进阶之路(基础篇) - 008 SPI数据传输(库函数方法)

spi基本概念

spi基本概念

进阶之路(基础篇) - 009 通过底层AVR方法实现SPI数据传输

Linux驱动开发20-SPI子系统分析