点击上方"蓝色小字"关注我哦
SPI 接口主要应用在 EEPROM, FLASH,实时时钟, AD 转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,这四根引脚分别是:
硬件连线如上图,从设备的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发送数据了。
编写从设备的驱动程序
理解了SPI如何与设备发送数据后,我们常常还需要编写从设备的驱动程序。我们首先要知道设备使用的是什么通信协议,如有的设备使用的I2C通信方式,有的则是SPI通信方式。
而不同的设备都会有不同的指令。这些指令也不过是主机按照基本的SPI通信协议发送的数据,只是其对从设备有特殊的意义,我们便是依靠通信来发送指令进而操作从设备的。
例如我们对从设备发送写指令,随后我们发送的数据便将写入从设备之中。从设备的指令集,往往有厂家给出,有时还会附带设备驱动案例。