一、SPI简介
1.SPI主从连接
SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线。SPI以主从方式工作,至少需要4根线,这四根线分别是MISO、MOSI、SCLK、CS。

图1. 全双工模式下SPI信号连接
一般来说,我们只需要对图1中出现的四个管脚进行配置即可控制SPI通信。
1)MISO:Master Input Slave Output。主机输入,从机输出。
2)MOSI:Master Output Slave Input。主机输出,从机输入。
3)SCLK:Serial Clock。主要作用是主机往从机传输时钟信号,控制数据交换的时机和速率。
4)CS/NSS:Chip Select。作为片选信号,用于主机片选从机,使被选中的从机能够被主机识别。
2.SPI时序问题:帧结构、时钟极性和时钟相位
◆帧结构:可以选择高位(MSB)在先或者低位(LSB)在先;SDIR=1B/0B, the MSB/LSB first
◆时钟极性:时钟极性(CPOL)是用来确定在SPI总线空闲的时候时钟线SCLK保持什么样的电平。若时钟极性配置为0,则SPI通信空闲状态时,串行时钟线SCLK保持低电平,反之,SPI通信空闲状态时,串行时钟线SCLK保持高电平。
◆时钟相位:时钟相位(CPHA)是用来确定数据传送是发生在时钟节拍的哪一个边沿。若CPHA配置为1则数据采样从第二个时钟边沿开始,反之数据采样从第一个时钟边沿开始。
二、抽象原则
1.作为一个通信接口,需要设置波特率,抽象出波特率设置函数;需要进行数据交换,抽象出读写字节的函数;
2.作为一个总线接口,拥有主从关系,需要对主机进行初始化,抽象出主机初始化函数;需要进行从选择,抽象出disable/enable从设备函数;
三、接口定义说明
1.SPI对外接口函数主要有下面几个:

1)其中,枚举类型hal_spi_index定义如下图所示:

下图定义了HAL层的spi配置列表,列表中的数据均使用宏定义来配置,配合hal_spi_index中的枚举变量,可以很方便的选用不同的spi设备以及更改SPI引脚。

2)上层应用需要设置SPI的波特率,所以将波特率给抽象了出来。例如在将SD初始化过程中需将SPI设置为低波特率进行初始化,当初始化完成后再使用高波特率进行数据传输。

3)SPI作为一个总线协议,需要对从设备进行选择,所以把disable/enable从设备抽象出来。

4)读写单字节的函数抽象为下图函数:其中spi为要选定的spi接口,TxData为要发送的数据,返回值为接收到的数据RxData;

5)因为在APP层中还有一个spi.h,所以将波特率、极性、相位均给抽象了出来,用于设置SPI数据发送过程中的时序配置;

四、适配
通过抽象这些接口,更改芯片时上层应用不需要更改,只需要把这些抽象接口进行适配即可。

