SPI 接口主要应用在 EEPROM, FLASH,实时时钟, AD 转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,这四根引脚分别是:
SS(Slave Select)从设备片选信号,由主设备控制。
SCK(Serial Clock)时钟信号,由主设备产生。
MISO(Master Output,Slave Input) 主设备数据输入,从设备数据输出。
MOSI(Master Input,Slave Output) 主设备数据输出,从设备数据输入。
硬件连线如上图,从设备的SCK,MOSI,MISO线均并联到主机MCU上,但片选信号线要直接连在主机MCU上,当片选信号线拉低时,则开启该从机与主机间的通信。
SPI根据时钟极性(CPOL)和时钟相位(CPHA)配置的不同,分为4种SPI模式。
时钟极性:当SPI通信设备处于空闲时(也可以认为是SPI通信开始时,即片选信号SS被拉低时),SCK信号线的电平信号。CPOL=0时,SCK在空闲状态时为低电平,CPOL=1时,SCK为高电平。
时钟相位:指数据采样的时刻。数据采样可以时发送,也可以是接收。当CPHA=0时,MOSI或MISO数据线上的信号将会在SCK时钟线的奇数边沿被采样。当CPHA=1时,数据线在SCK偶数边沿采样。
这选择主机四种模式时要看从机的模式,因为按照SPI通信的协议,主从双方使用的SPI模式应该一致,而并不是所有的从机设备都支持SPI的四种通信模式,可能只能支持其中的两种,这时选择模式时就要注意了。
那SPI通信发送的过程是怎么样的呢?
首先应该拉低我们要进行通信的从机设备片选信号SS,这个就不必多说了。
然后,以时钟极性CPOL为0,时钟相位CPHA为0时(即初始时钟为低电平,在第奇数个时钟跳变信号,即上升沿时发送数据)为例:
数据(不论是发送的数据还是要接收的)在跳变信号到来前准备好,在时钟跳变时(上图为时钟上升沿)将数据发送出去,并开始准备新的数据。
因此,我们可以通过三个标志位完全监控SPI通信的状态:
发送缓冲器空闲标志(TXE):
此标志为1时表明发送缓冲器为空,可以写入下一个待发送的数据。
接收缓冲期非空(RXNE):
此标志位为1时表明在接收缓冲器中包含有效的接收数据。
忙(Busy)标志:
BUSY标志有硬件设置与清除(写入此位无效果)。
这时我们便可以理解下面函数内容了:
其中,SPI_I2S_GetFlagStatus();函数为检测标志位的库函数,SPI_I2S_SendData();和SPI_I2S_ReceiveData();为接收和发送数据的库函数。
SPI初始化
上述程序实现了接收和发送一个字节。
那SPI初始化配置是如何的呢?
上图为SPI初始化函数。
1:1处我们看出,我们可以用此SPI与多种设备进行通信。如果我们想用一个SPI接口同时连接这三个设备,并分别与之通信,就如本文第一张图所画那样。就需要三个片选信号线,但从下图可看出SPI1接口规定的只有一个片选信号线NSS。但其实没有关系,我们可以通过软件设置一个引脚拉低拉高就可以了。
2:在2处初始化了3个引脚分别为SPI1_SCK,SPI1_MISO,SPI1_MOSI。
3:3处即为SPI接口初始化,结构体如图:
SPI_Direction:选择数据传输是单向还是双向
SPI_Mode:设置SPI模式为主机模式还是从机模式。若为主机模式,则时钟SCK由主机产生。
SPI_DataSize:每次通信数据包大小。可以为8位或者16位。
SPI_CPOL和SPI_CPHA分别位时钟极性和时钟相位
SPI_NSS:可设置为硬件模式或软件模式。硬件模式是SPI片选信号可自动产生,而软件模式则需要我们亲自把相应的GPIO口拉高或置低产生片选或非片选信号。如果我们需要同多个从设备进行通信,则往往设为软件模式。
SPI_BaudRatePrescaler:设置波特率分频值,可以为2,4,6,8,16,32,64,128,256。
SPI_FirstBit:所有串行的通信协议都会由MSB先行(高位数据在前)还是LSB先行(低位数据在前)的问题。
SPI_CRCPolynomial:SPI的CRC效验中的多项式。CRC校验仅用于保证全双工通信的可靠性。数据发送和数据接收分别使用单独的CRC计算器。通过对每一个接收位进行可编程的多项式运算来计算CRC。CRC的计算是在由SPI_CR1寄存器中CPHA和CPOL位定义的采样时钟边沿进行的。
按照原子哥的程序配置,我们便可以实现SPI发送数据了。
编写从设备的驱动程序
理解了SPI如何与设备发送数据后,我们常常还需要编写从设备的驱动程序。我们首先要知道设备使用的是什么通信协议,如有的设备使用的I2C通信方式,有的则是SPI通信方式。
而不同的设备都会有不同的指令。这些指令也不过是主机按照基本的SPI通信协议发送的数据,只是其对从设备有特殊的意义,我们便是依靠通信来发送指令进而操作从设备的。
例如我们对从设备发送写指令,随后我们发送的数据便将写入从设备之中。从设备的指令集,往往有厂家给出,有时还会附带设备驱动案例。