SPI知识
SPI是全双工同步串行协议。全双工意味着使用SPI的设备可以在同一时刻输入和输出数据;同步意味必须要通过时钟信号来确定何时收发数据;串行意味着收发数据是一位接着一位的。
线路
SPI总共有4种类型的线路,分别为CS(SS),SCLK,MOSI,MISO。SS线可以有多根,其他类型的线只能一个
SS(CS)为片选信号线,通常情况下拉高意味着master与该cs接的slave不进行通信,拉低意味着master与该cs接的slave进行通信。
SCLK为时钟线,时钟线只能由master进行控制。
MOSI(master output slave input),这根线用于主机发送数据,从机接收数据。
MISO(master input slave output),这根线用于从机发送数据主机接受数据。
设备之间的连接关系
SPI可以实现一主一从,也可以实现一主多从。
SPI实现一主一从非常简单,重点叙述一下一主多从。
有多条CS线
则每个CS线连接一个设备,当选中一个从设备时,就把该cs线上的电平拉低。当然如果同时将两条CS线拉低,会造成设备交换混乱。具体如图
菊花链
若主设备只有一条CS线,则可以使用菊花链进行信号传输。主设备通过MOSI把信号发送给第一个从设备,第一从设备从MISO信号线发送给第二从设备(用该设备的MOSI线接受)...最后一个从设备通过MISO线把数据传回给从设备。具体如下
菊花链有个巨大的确点是并行传输,只要其中一个设备坏了,下一级设备就接收不到信息了。
通信模式和时序逻辑
SPI有4种通信模式,由CPOL和CPHA决定采用哪一种通信模式(在何时传输数据以及何时采样)。
模式0: CPOL = 0,CPHA = 0
该模式时数据空闲状态为低电平,即SCLK为高电平时读取的数据为有效。接收设备在第一个边沿(上升沿读取数据)。
模式1: CPOL = 0,CPHA = 1
该模式时数据空闲状态为低电平,即SCLK为高电平时读取的数据为有效。接收设备在第2个边沿(上升沿读取数据)。
模式2: CPOL = 1,CPHA = 0
该模式时数据空闲状态为高电平,即SCLK为低电平时读取的数据为有效。接收设备在第一个边沿(上升沿读取数据)。
模式3: CPOL = 1,CPHA = 1
该模式时数据空闲状态为高电平,即SCLK为低电平时读取的数据为有效。接收设备在第2个边沿(上升沿读取数据)。
可能会有人有疑问,CPOL = 0,CPHA = 0这种模式时,发送设备最开始发送的那一位数据是在什么时候呢?是在知道CS为低电平的那一刻立即发出的。详见
优缺点
优点
1:全双工串行通信,可以以较高的速率进行收发数据。
2:不限制数据传输格式,数据传输格式极其灵活。
缺点
1:不确定数据是否接收。
2:没有纠错功能。
传输例子
stm32 SPI
typedef struct
{
uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode.
This parameter can be a value of @ref SPI_data_direction */
uint16_t SPI_Mode; /*!< Specifies the SPI operating mode.
This parameter can be a value of @ref SPI_mode */
uint16_t SPI_DataSize; /*!< Specifies the SPI data size.
This parameter can be a value of @ref SPI_data_size */
uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state.
This parameter can be a value of @ref SPI_Clock_Polarity */
uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture.
This parameter can be a value of @ref SPI_Clock_Phase */
uint16_t SPI_NSS; /*!< Specifies whether the NSS signal is managed by
hardware (NSS pin) or by software using the SSI bit.
This parameter can be a value of @ref SPI_Slave_Select_management */
uint16_t SPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be
used to configure the transmit and receive SCK clock.
This parameter can be a value of @ref SPI_BaudRate_Prescaler.
@note The communication clock is derived from the master
clock. The slave clock does not need to be set. */
uint16_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit.
This parameter can be a value of @ref SPI_MSB_LSB_transmission */
uint16_t SPI_CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. */
}SPI_InitTypeDef;
这是stm32 spi初始化结构体,了解上面内容就几乎明白了怎么初始化。
uint16_t SPI_NSS; 是软选还是硬选
uint16_t SPI_BaudRatePrescaler 确定sclk的频率。
uint16_t SPI_FirstBit; MSB还是LSB
uint16_t SPI_CRCPolynomial; CRC校验,但是不开的话是没有用处的。