SPI介绍
SPI(Serial Peripheral Interface)是主从式同步串列通讯,可分为单工/半双工/全双工。
主要应用在EEPROM、快闪记忆体、AD转换、部分LCD上都会使用,SPI属于高速、全双工且具同步的通讯网路,连结外部设备时只需要四条线就可以完成通讯,同时节省了空间。
SPI可以分为Master与Slave两种模式,但需注意的是一个SPI通讯系统中只可以有一个Master设备,所以的操作都会由Master主动发起,若连接多个设备时则可以透过CS来选择要通讯的Slave。
优点: 仅需4条线有效减少空间、全双工通讯、资料传送快
缺点: 没有ACK机制,在资料可靠度较差,需要由使用者自行确定资料正确
STM32中的SPI:
3线全双工同步传输(SPI1,SPI2,SPI3)8 bit or 16 bit 传输选择可由软体or硬体选择CS可以触发中断发送与接收旗标SPI Pin脚说明
SPI Pin脚
具有4条线(3线也行但仅限单向传输EX:主设备传送至从设备),四条线分别为MISO、MOSI、SCLK、CS


SPI Protocol
SPI通讯有4种不同的模式,可以查找设备的DataSheet看看支援那些模式~
CPOL=0,当SCLK=0时属于空闲状态,所以有效状态是SCLK在高电位时CPOL=1,当SCLK=1时属于空闲状态,所以有效状态是SCLK在低电位时CPHA=0,代表的是资料採样是在第1个边缘,资料发送在第2个边缘CPHA=1,代表的是资料採样是在第2个边缘,资料发送在第1个边缘CPOL : 用来设定SCLK的电位,什么时候是忙碌什么时候是空闲
CPHA : 决定资料採样点是在第几个边缘

总结一下四种模式的特性:
CPOL= 0 CPHA = 0 : 代表SCLK低电位时为空闲状态,由低电位转为高电位时进行採样,也就是上升沿。(第一个边缘)
CPOL= 0 CPHA = 1 : 代表SCLK低电位时为空闲状态,由高电位转为低电位时进行採样,也就是下降沿(第二个边缘)
CPOL= 1 CPHA = 0 : 代表SCLK高电位时为空闲状态,由高电位转为低电位时进行採样,也就是下升沿。(第一个边缘)
CPOL= 1 CPHA = 1 : 代表SCLK高电位时为空闲状态,由低电位转为高电位时进行採样,也就是上升沿。(第二个边缘)
比较UART与SPI
UART 与 SPI 接线方式,下图为UART接线方法可以看到两设备为TX与RX分别对接,同时仅能进行一对一传输,无法像SPI设备可以达到一对多的传输。UART为全双工、异步通讯且没有SCLK线,所以事先要先设定好baud rate,速度较慢,而SPI是全双工且因具有SCLK线可以执行同步通讯,传输速率较高。UART通讯架构
SPI通讯架构
函数介绍
SPI传送 : 轮询方式//hspi SPI编号//pData 要发送的资料//Size 资料大小 (byte)//TimeOut 逾时HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
SPI接收 : 轮询方式//hspi SPI编号//pData 资料接收buf//Size 资料大小 (byte)//TimeOut 逾时HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
SPI接收与传送 : 轮询方式,传送与接收同步进行。(SPI工作方式是每发送1个bit就会同步接收一个bit),在使用是要注意所设的缓冲器大小
//hspi SPI编号//pTxData//pRxData 资料接收buf//Size 资料大小 (byte)//TimeOut 逾时HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,uint32_t Timeout)
同样的与前面所提到USART一样,除了轮询方式以外同样有中断的传送方式~
SPI 传送 : 透过中断方式//hspi SPI编号//pData 要发送的资料//Size 资料大小 (byte)//TimeOut 逾时HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
SPI接收 : 透过中断方式//hspi SPI编号//pData 资料接收buf//Size 资料大小 (byte)//TimeOut 逾时HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
SPI接收与传送 : 透过中断方式,传送与接收同步进行。//hspi SPI编号//pTxData//pRxData 资料接收buf//Size 资料大小 (byte)//TimeOut 逾时HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
SPI 接收回调函数__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi){ /* Prevent unused argument(s) compilation warning */ UNUSED(hspi); /* NOTE : This function should not be modified, when the callback is needed, the HAL_SPI_RxCpltCallback should be implemented in the user file */}
SPI 传送回调函数__weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi){ /* Prevent unused argument(s) compilation warning */ UNUSED(hspi); /* NOTE : This function should not be modified, when the callback is needed, the HAL_SPI_TxRxCpltCallback should be implemented in the user file */}