One article teaches you to thoroughly learn the SPI protocol

1. Overview SPI

The SPI protocol is a communication protocol (Serial Peripheral Interface) proposed by Motorola, namely the Serial Peripheral Interface, which is a high-speed full-duplex communication bus. It is widely used between ADC, LCD and other equipment and MCU, where a higher communication rate is required. Here you can compare another blog I wrote to teach you to thoroughly learn the IIC protocol
1. Signal line: SPI has SCK, MOSI, MISO, and CS lines (different from IIC only CLK, SDA).
2. Addressing mode: SPI selects the slave device through the CS chip select signal (IIC finds the slave device through addressing)
3. Communication rate: The SPI rate is faster (up to fPCLK/2), generally used for high-speed devices Inter-communication (different from IIC)

PI is different from IIC, SPI has a clock line, MOSI (master output slave input line), MISO (zh)
insert image description here

2. SPI connection

2.1 One master and one slave

In the "one master one slave" SPI interconnection mode, only one SPI master device communicates with one SPI slave device. In this case, you only need to directly connect the SCK, MOSI, and MISO of the master device to the SCK, MOSI, and MISO of the slave device, and set the SS of the master device to high level, and the SS of the slave device to ground (that is, set the Ping, chip selection is valid, select the slave device).

insert image description here

2.2 One master and multiple slaves

In the "one master and multiple slaves" SPI interconnection mode, one SPI master device can communicate with multiple SPI slave devices. In this case, all SPI devices (including master and slave) share the clock line and data line, that is, SCK, MOSI, MISO 3 lines, and use multiple GPIO pins on the master side to select different SPI from the device.
insert image description here

3. SPI communication process

Before talking about the communication process, let's talk about polarity and phase. The subsequent sampling process can only be understood later.

3.1 CPOL (polarity) and CPHA (phase)

The CPHA (clock phase) bit is cleared to "0", and the data is sampled at the odd (1st, 3rd, 5th...) transition edges of the SCK clock. The
CPHA (clock phase) bit is set to "1", and the data is sampled at the SCK clock's Even-numbered (2nd, 4th, 6th...) jump edge sampling.
When the CPOL bit is "0", it means that the SCK is 0 when it is idle, and when the CPOL bit is "1", it means that the SCK is 1 when it is idle.
So, CPOL determines whether the first edge is a rising edge or a falling edge. If SCK idle is 0, then the first edge is the rising edge. If SCK is 1 when idle, then the first edge is the falling edge.
So in general, CPHA and CPOL determine whether to sample on the rising edge or on the falling edge.
So there are a total of 4 combinations, which determine that SPI has 4 modes. The general table is as follows:
insert image description here

3.2 SPI Timing Diagram

This is the communication sequence of a host, we take SPI mode 0 as an example. The NSS, SCK, and MOSI signals are all controlled by the host, while the MISO signal
is generated by the slave, and the host reads the data of the slave through this signal line. The MOSI and MISO signals
are valid only when NSS is at low level, and MOSI and MISO transmit one bit of data in each clock cycle of SCK.
SPI's clock signal has phase and polarity

3.1 SPI start signal

The NSS signal line changes from high to low, which is the start signal of SPI communication. NSS is the exclusive signal line of each slave. When the slave detects the start signal on its own NSS line, it knows that it has been selected by the master and starts to communicate with the master.

3.2 SPI stop signal

The NSS signal changes from low to high, which is the stop signal of SPI communication, indicating that the communication is over and the selected state of the slave is cancelled.

3.3 Data availability

SPI uses MOSI and MISO signal lines to transmit data, and uses SCK signal line for data synchronization. The MOSI and MISO data lines transmit one bit of data in each clock cycle of SCK, and the data input and output are carried out simultaneously . During data transmission, MSB first or LSB first is not strictly regulated, but it is necessary to ensure that the same protocol is used between the two SPI communication devices. The data of MOSI and MISO changes during the rising edge of SCK and is output during the falling edge of SCK . is sampled. That is to say, at the falling edge of SCK, the data of MOSI and MISO are valid. When the level is high, it means data "1", when it is low level, it means data "0". At other times, the data is invalid, and MOSI and MISO prepare for the next representation of data. Each SPI data transfer can be in 8-bit or 16-bit units, and the number of units per transfer is not limited.

4. Code example

Here we take the communication with Flash as an example, the following is an initialization code

void SPI_FLASH_Init(void)
{
    
    
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
	
	/* 使能SPI时钟 */
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE );
	
	/* 使能SPI引脚相关的时钟 
	1.片选引脚 2.SCK时钟引脚 3.MISO引脚 4.MOSI引脚 */
 	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOA|
																	     RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOA, ENABLE );
	
  /* 配置SPI的 CS引脚,普通IO即可 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
	
  /* 配置SPI的 SCK引脚*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* 配置SPI的 MISO引脚*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* 配置SPI的 MOSI引脚*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* 停止信号 FLASH: CS引脚高电平*/
  GPIO_SetBits(GPIOA,GPIO_Pin_4);

  /* SPI 模式配置 */
  // FLASH芯片 支持SPI模式0及模式3,据此设置CPOL CPHA
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//全双工模式
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;  //主机
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;  //极性高
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;  //偶边沿
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;   //软件控制
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;  //速率4分频
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;  //高位先行
  SPI_InitStructure.SPI_CRCPolynomial = 7;           //数据校验 --一般不需要
  SPI_Init(FLASH_SPIx , &SPI_InitStructure);      //初始化结构体

  /* 使能 SPI  */
  SPI_Cmd(SPI1 , ENABLE);
	
}

Guess you like

Origin blog.csdn.net/qq_62553914/article/details/131268296