STM32 study notes-SPI introduction and configuration

SPI is the abbreviation of English Serial Peripheral interface, as the name implies, is the serial peripheral interface. Motorola first defined it on its MC68HCXX series processors. The SPI interface is mainly used between EEPROM, FLASH, real-time clock, AD converter, digital signal processor and digital signal decoder. SPI is a high-speed, full-duplex, and synchronous communication bus, and it occupies only four lines on the pins of the chip, which saves the pins of the chip, and at the same time saves space and provides convenience for the PCB layout. Because of this simple and easy-to-use feature, more and more chips now integrate this communication protocol, and STM32 also has an SPI interface. Let's take a look at the internal concise diagram of SPI (Figure 29.1.1):
Insert picture description here
SPI interface generally uses 4 wires for communication:
MISO master device data input, slave device data output.
MOSI master device data output, slave device data input.
SCLK clock signal, generated by the master device.
CS slave device chip select signal, controlled by the master device.

It can be seen from the figure that both the master and the slave have a serial shift register, and the master
initiates a transfer by writing a byte to its SPI serial register . The register transmits the byte to the slave through the MOSI signal line, and the slave also returns the contents of its shift register to the master through the MISO signal line. In this way, the contents of the two shift registers are exchanged. The write operation and read operation of the peripheral are completed synchronously. If only write operation, 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 transfer from the slave.
The main features of SPI are: it can send and receive serial data at the same time; it can work as a master or a slave; it provides a frequency
programmable clock; the transmission end interrupt flag; write conflict protection; bus competition protection.

Four working modes of SPI bus In order to exchange data with peripherals, the SPI module can configure its output serial synchronization clock polarity and phase according to the working requirements of the peripherals. The clock polarity (CPOL) has no significant impact on the transmission protocol. If CPOL=0, the idle state of the serial synchronous clock is low; if CPOL=1, the idle state of the serial synchronous clock is high. The clock phase (CPHA) can be configured to select one of two different transmission protocols for data transmission. If CPHA=0, the data is sampled on the first edge (rising or falling) of the serial synchronous clock; if CPHA=1, the data is sampled on the second edge (rising or falling) of the serial synchronous clock sampling. The clock phase and polarity of the SPI master module and the external device communicating with it should be consistent.

The configuration steps are as follows:

1) Configure the multiplexing functions of related pins, enable SPI2 clock, IO initialization
2) Initialize SPI2, set SPI2 working mode

void SPI_Init(SPI_TypeDef* SPIx, PI_InitTypeDef* SPI_InitStruct)

3) Enable SPI2

SPI_Cmd(SPI2, ENABLE); //使能 SPI 外设

4) SPI transfer data

void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data)

5) View SPI transmission status

SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE)
//以下是SPI模块的初始化代码,配置成主机模式,访问SD Card/W25Q64/NRF24L01						  
//SPI口初始化
//这里针是对SPI2的初始化

void SPI2_Init(void)
{
    
    
 	GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;

	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能 
	RCC_APB1PeriphClockCmd(	RCC_APB1Periph_SPI2,  ENABLE );//SPI2时钟使能 	
 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //PB13/14/15复用推挽输出 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB

 	GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);  //PB13/14/15上拉

	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		//设置SPI工作模式:设置为主SPI
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//设置SPI的数据大小:SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;		//串行同步时钟的空闲状态为高电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;	//串行同步时钟的第二个跳变沿(上升或下降)数据被采样
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;		//定义波特率预分频的值:波特率预分频值为256
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;	//CRC值计算的多项式
	SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
 
	SPI_Cmd(SPI2, ENABLE); //使能SPI外设
	
	SPI2_ReadWriteByte(0xff);//启动传输		 
 

}   
//SPI 速度设置函数
//SpeedSet:
//SPI_BaudRatePrescaler_2   2分频   
//SPI_BaudRatePrescaler_8   8分频   
//SPI_BaudRatePrescaler_16  16分频  
//SPI_BaudRatePrescaler_256 256分频 
  
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
{
    
    
  assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
	SPI2->CR1&=0XFFC7;
	SPI2->CR1|=SPI_BaudRatePrescaler;	//设置SPI2速度 
	SPI_Cmd(SPI2,ENABLE); 

} 

//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI2_ReadWriteByte(u8 TxData)
{
    
    		
	u8 retry=0;				 	
	while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
		{
    
    
		retry++;
		if(retry>200)return 0;
		}			  
	SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据
	retry=0;

	while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
		{
    
    
		retry++;
		if(retry>200)return 0;
		}	  						    
	return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据					    
}

Guess you like

Origin blog.csdn.net/Summertrainxy/article/details/105417757