STM32F1xx official information:
"STM32 Chinese Reference Manual V10" - Chapter 23 Serial Peripheral Interface SPI
Basic Introduction to SPI
Introduction to SPI
SPI is the abbreviation of Serial Peripheral interface. As the name suggests, it is a serial peripheral interface. It was first defined by Motorola on its MC68HCXX series processors.
SPI interface is mainly used in EEPROM, FLASH, real-time clock, AD converter, and between digital signal processor and digital signal decoder. SPI is a high-speed, full-duplex, synchronous communication bus, and only occupies four wires on the chip pins, saving the chip pins and saving space on PCB layout, providing convenience. It is precisely because of this simple and easy-to-use feature that more and more chips now integrate this communication protocol, such as AT91RM9200.
SPI is divided into two modes: master and slave. An SPI communication system needs to include one (and only one) master device and one or more slave devices. The read and write operations of the SPI interface are all initiated by the master device. When there are multiple slave devices, they are managed through their respective chip select signals.
Advantages: support full-duplex communication, simple communication, fast data transmission rate;
Disadvantages: There is no specified flow control, and no response mechanism to confirm whether the data is received, so there are certain defects in data reliability compared with the IIC bus protocol.
Characteristics of SPI interface in STM32
3-wire full-duplex synchronous transmission;
8 or 16-bit transmission frame format selection;
Master or slave operation, support multi-master mode;
NSS management can be performed by software or hardware in both master and slave modes: dynamic change of master/slave operation mode;
Programmable clock polarity and phase;
Programmable data order, MSB first or LSB first;
Dedicated transmit and receive flags that can trigger interrupts;
SPI bus busy status flag;
Hardware CRC to support reliable communication;
Master mode fault, overload, and CRC error flags that can trigger interrupts;
1-byte transmit and receive buffers supporting DMA function: Generates transmit and receive requests.
SPI Protocol
SPI Pin Description
The communication principle of SPI is very simple. It works in master-slave mode. This mode usually has one master device and one or more slave devices, which requires at least 4 wires. In fact, 3 wires are also acceptable (for unidirectional transmission). These four wires are MISO, MOSI, SCLK, and CS. See the table below for specific descriptions:
Description of SPI lines
Name Description
MISO master device data output, slave device data input
MOSI master device data output, slave device data input
SCLK clock signal, generated by the master device
CS chip select signal, master device control
CS: controls whether the chip is selected, that is, only when the chip select signal is a predetermined enable signal (usually low voltage by default), the operation of this chip is effective, which makes it possible to connect multiple SPI devices on the same bus.
That is to say: when there are multiple slave devices, because each slave device has a chip select pin connected to the master device, when our master device communicates with a slave device, it is necessary to pull down the chip select pin level of the slave device.
MISO/MOSI/SCLK: Communication is completed through data exchange. Here we must first know that SPI is a serial communication protocol, which means that data is transmitted one bit at a time. This is why the SCLK clock line exists. SCLK provides clock pulses, and MISO and MOSI complete data transmission based on this pulse. Data output is through the MOSI line, and data is sampled at the rising or falling edge of the clock. At the same time, there will be return data for reception. The same principle is used for input to complete one bit of data transmission. In this way, 8 bits of data can be transmitted at least 8 times the clock signal changes (one rising edge and one falling edge).
To be careful of:
The SCLK signal line is only controlled by the master device, and the slave device cannot control the signal line. Similarly, in an SPI-based device, there is at least one master device;
In point-to-point communication, the SPI interface does not require addressing operations and is full-duplex communication, which is simple and efficient. In a system with multiple slave devices, each slave device requires an independent enable signal, which is slightly more complicated in hardware than the I2C system.
SPI communication mode
SPI communication has 4 different modes. Different slave devices may be configured to a certain mode at the factory, which cannot be changed; but our communication parties must work in the same mode, so we can configure the SPI mode of our master device and control the communication mode of our master device through CPOL (clock polarity) and CPHA (clock phase), as follows:
SPI communication mode
Mode CPOL (Clock Polarity) CPHA (Clock Phase)
MODE0 0 0
MODE1 0 1
MODE2 1 0
MODE3 1 1
The clock polarity CPOL is used to configure the state of the SCLK level as idle or valid, and the clock phase CPHA is used to configure the edge at which the data is sampled:
CPOL=0 means that when SCLK=0, it is in idle state, so the effective state is when SCLK is at high level;
CPOL=1 means that when SCLK=1, it is in idle state, so the effective state is when SCLK is at low level;
CPHA=0 means data sampling is on the first edge and data transmission is on the second edge;
CPHA=1 means that data sampling is on the second edge and data transmission is on the first edge.
The timing diagrams of the four specific modes are as follows:
To sum up, the four communication modes of SPI are:
CPOL=0, CPHA=0: In idle state, SCLK is at low level, data sampling is on the first edge, that is, SCLK jumps from low level to high level, so data sampling is on the rising edge;
CPOL=0, CPHA=1: In idle state, SCLK is at a low level, and data is sent on the first edge, that is, SCLK jumps from a low level to a high level, so data sampling is on the falling edge;
CPOL=1, CPHA=0: In idle state, SCLK is at a high level, and data is collected on the first edge, that is, when SCLK jumps from a high level to a low level, data is collected on the falling edge.
CPOL=1, CPHA=1: In idle state, SCLK is at a high level, and data is sent on the first edge, that is, SCLK jumps from a high level to a low level, so data collection is on the rising edge.
Internal working mechanism of SPI
The following is a diagram of a SPI single master and single slave connection to understand its internal working mechanism:
There are 4 wires in hardware;
Both the master and slave have a serial shift register, and the master initiates a transfer by writing a byte to its SPI serial register;
The serial shift register transmits the byte to the slave through the MOSI signal line, and the slave also returns the contents of its serial shift register to the master through the MISO signal line. In this way, the contents of the two shift registers are exchanged;
The write and read operations of the peripheral are completed synchronously. If only a write operation is performed, the host only needs to ignore the received byte; conversely, if the host wants to read a byte from the slave, it must send a null byte to trigger the slave's transmission.
In other words, SPI is a ring bus structure, consisting of CS, SCLK, MISO, and MOSI. Its timing is actually very simple. Under the control of SCLK, data is moved out of the host register and the slave register in sequence from high to low, and is moved into the slave register and the host register in sequence. When all the contents in the register are moved out, it is equivalent to completing the exchange of the contents of the two registers.
Assume that the 8-bit register of the host is loaded with the data to be sent, 10101010, the rising edge is sent, the falling edge is received, and the high bit is sent first. Then when the first rising edge comes, the host will transmit the highest bit 1 to the slave through the MOSI signal line, and its own register will become 0101010x. At the same time, the MISO signal line will return a data from the slave to the host, so the register is 0101010MISO at this time. In this way, after 8 clock pulses, the contents of the two registers are exchanged once. In this way, an SPI timing is completed.
At this time, there will be a question, or a necessity:
Why does the slave return data to the master through MISO when the master sends data to the slave?
Explanation: The data transmission of the host and the slave is completed at the same time, and the data reception of both is also completed at the same time. That is to say, when the host sends data on the rising edge, the slave also sends data.
Therefore, in order to ensure correct communication between the master and slave devices, their SPI should have the same clock polarity and clock phase.
SPI interface of STM32
SPI can be divided into master and slave modes, and supports full-duplex mode, so the SPI interface of STM32 is relatively complex. For example: configure SPI as master mode, configure SPI as slave mode, configure SPI as simplex communication, configure SPI as duplex communication, etc. The content here is very large, and there are many register bits involved, so I will not introduce too much. If you want to know more, you can check Chapter 23 of the official document of STM32F1xx.
Block diagram of the SPI interface
SPI Pins
The SPI interface of STM32 is connected to external devices through 4 pins, which is consistent with the standard SPI protocol:
MISO: Master input/slave output pin. This pin sends data in slave mode and receives data in master mode.
MOSI: Master output/slave input pin. This pin sends data in master mode and receives data in slave mode.
SCK: serial port clock, as the input of the master device and the input of the slave device;
NSS: Slave Select. This is an optional pin used to select the master/slave device. Its function is to be used as a "chip select pin" so that the master device can communicate with a specific slave device individually to avoid conflicts on the data line.
Slave Selection (NSS) Foot Management
There are 2 NSS modes:
Software NSS mode: This mode can be enabled by setting the SSM bit of the SPI_CR1 register. In this mode, the NSS pin can be used for other purposes, and the internal NSS signal level can be driven by writing the SSI bit of the SPI_CR1 register;
Hardware NSS mode is divided into two cases:
NSS output is enabled: When the STM32F10xxx works as the master SPI, and the NSS output has been enabled by the SSOE bit of the SPI_CR2 register, the NSS pin is pulled low, and all SPI devices whose NSS pins are connected to the NSS pin of the master SPI and configured as hardware NSS will automatically become slave SPI devices. When an SPI device needs to send broadcast data, it must pull the NSS signal low to notify all other devices that it is the master device; if it cannot pull NSS low, it means that there is another master device communicating on the bus, and a hardware failure error will be generated;
NSS export is disabled: allows operation in a multi-master environment.
Data frame format
Depending on the LSBFIRST bit in the SPI_CR1 register, the output data bits can be left-aligned (MSB alignment standard) or right-aligned (LSB alignment standard).
Each data frame can be 8 or 16 bits depending on the DFF bit in the SPI_CR1 register. The selected data frame format is valid for both transmission and/or reception.
Status Flags
The application can fully monitor the status of the SPI bus through 3 status flags:
Transmit buffer empty flag (TXE)
When this flag is 1, it indicates that the transmit buffer is empty and the next data to be transmitted can be written into the buffer. When writing to SPI_DR, the TXE flag is cleared.
Receive buffer not empty (RXNE)
This flag indicates that the receive buffer contains valid receive data when it is 1. This flag can be cleared by reading the SPI data register.
Busy sign
The BSY flag is set and cleared by hardware (writing to this bit has no effect). This flag indicates the status of the SPI communication layer.
When it is set to 1, it indicates that the SPI is busy communicating, with one exception: in bidirectional receive mode of the master mode (MSTR=1, BDM=1 and BDOE=0), the BSY flag remains low during reception.
Before the software turns off the SPI module and enters stop mode (or turns off the device clock), the BSY flag can be used to detect whether the transmission is completed. This can avoid destroying the last transmission. Therefore, it is necessary to strictly follow the following process.
SPI Interrupt
SPI pins of STM32
SPI Pin Location
GPIO configuration of peripherals
SPI related configuration library functions
1 initialization function
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);
Function: Initialize SPI related parameters, such as direction (full-duplex), master-slave mode, data size, CPOL, CPHA, chip select software mode, pre-scaling coefficient, etc.
3 enable functions
void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);
void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState);
Function: Enable SPI interface; enable SPI interrupt; enable SPI DMA function.
2 data transfer functions
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);
Function: used for SPI to transmit data and receive data respectively.
4 status bit functions
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
Function: The first two are used to obtain and clear various status bits of SPI; the latter two are for the interrupt flag bits of SPI.
SPI general steps
Experimental goal: Use SPI2 to perform initialization and other operations.
Configure the multiplexing function of related pins and enable the SPIx clock. Call function: void GPIO_Init();
Initialize SPIx and set SPIx working mode. Call function: void SPI_Init();
Enable SPIx. Calling function: void SPI_Cmd();
SPI transmits data. Calling function: void SPI_I2S_SendData(); uint16_t SPI_I2S_ReceiveData();
Check the SPI transmission status. Call function: SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE).
Follow these general steps to create a simple SPI program:
void SPI2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //PORTB clock enable
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE ); //SPI2 clock enable
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PB13/14/15 multiplexed push-pull output
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //Initialize GPIOB
GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //PB13/14/15上拉
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //Set SPI unidirectional or bidirectional data mode: SPI is set to two-line bidirectional full-duplex
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //Set SPI working mode: set to master SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //Set the SPI data size: SPI sends and receives 8-bit frame structure
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //The idle state of the serial synchronous clock is high
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //The second transition edge (rising or falling) of the serial synchronous clock is used to sample the data
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS signal is managed by hardware (NSS pin) or software (using SSI bit): internal NSS signal is controlled by SSI bit
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //Define the baud rate prescaler value: the baud rate prescaler value is 256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //Specify whether data transmission starts from the MSB bit or the LSB bit: Data transmission starts from the MSB bit
SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC value calculation polynomial
SPI_Init(SPI2, &SPI_InitStructure); //Initialize the peripheral SPIx registers according to the parameters specified in SPI_InitStruct
SPI_Cmd(SPI2, ENABLE); //Enable SPI peripheral
SPI2_ReadWriteByte(0xff); //Start transmission
}
//SPI speed setting function
//SpeedSet:
//SPI_BaudRatePrescaler_2 2-division
//SPI_BaudRatePrescaler_8 8-frequency division
//SPI_BaudRatePrescaler_16 16 division
//SPI_BaudRatePrescaler_256 256 division
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
SPI2->CR1&=0XFFC7;
SPI2->CR1|=SPI_BaudRatePrescaler; //Set SPI2 speed
SPI_Cmd(SPI2,ENABLE);
}
//SPIx read and write a byte
//TxData: Bytes to be written
//Return value: the bytes read
u8 SPI2_ReadWriteByte(u8 TxData)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) // Check if the specified SPI flag is set: send buffer empty flag
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI2, TxData); //Send a data through peripheral SPIx
retry=0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) // Check whether the specified SPI flag is set: receive buffer not empty flag
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI2); //Return the data most recently received via SPIx
Previous article:STM32 Light up LED
Next article:[STM32] Basic principle example of IIC: Common IO port simulates IIC timing to read 24C02
- Popular Resources
- Popular amplifiers
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- What exactly is the input and output voltage range of an operational amplifier?
- Micropython version that supports MCPWM function
- [Transfer] Teach you how to scan the most keys with the least IO ports
- How to solve the problem of No rule to make target when developing zynq using xilinx SDK
- Design of control system for CNC engraving machine based on embedded system
- Measurement and control, come and have a look
- Development environment installation (II) Cross-compilation environment
- Circuit Design of Filters and Attenuators
- Interpretation and test application of IEC harmonic standards
- A winding method for wound core transformer winding