The STM32 SPI and FPGA communication

本文详细介绍了STM32 SPI总线通信原理,包括四根线(时钟、芯片选择、接收、发送)的工作机制,并提供了具体的初始化配置代码。同时,文章阐述了如何在STM32为主机的情况下,通过软件控制FPGA的SPI接口,实现数据的读写操作,以及数据传输格式的设置。具体包括了读取和写入函数的实现,以及在不同SPI模式下,如何有效控制CS(芯片选择)信号的高低电平,以确保数据传输的正确性和效率。

The STM32 SPI and FPGA communication

STM32 spi bus communication 

SPI bus in the study, the protocol and hardware description is not to say that the four-wire, including clock, chip select, receive, send 

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; / / full-duplex 
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; / / master mode 
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; / / 16bit width 
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; 
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; 
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; 
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; / / 2 - 18MHz; 4 - 9MHz; 8 - 4.5MHz 
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; / / high byte first 
SPI_InitStructure.SPI_CRCPolynomial = 7; 
SPI_Init (SPIx, & SPI_InitStructure); 
SPI_Cmd (SPIx, ENABLE); 

SPI has no hardware control CS, can only be controlled by the software is by NSS the external GPIO to control. 

Like my projects STM32 communication with the FPGA, the FPGA SPI In this state as a master of the STM32,

CS transmission data is low after the transmission must be pulled so that the FPGA can be judged SPI Transfer start and end state. 

FPGA data transfer format is 16bit address +16 bit data for read 16bit 

uint16_t spi_read (SPI_TypeDef * SPIx, uint32_t addr) 
{ 
uint16_t value; 
The uint16_t spi_nss; 
uint16_t add; 
uint32_t level; 


if (SPI1 == SPIx) 
spi_nss = SPI1_PIN_NSS; 
else if (SPI2 == SPIx) 
spi_nss = SPI2_PIN_NSS; 


while (SPI_I2S_GetFlagStatus (SPIx, SPI_I2S_FLAG_TXE) == RESET); 
GPIO_ResetBits (GPIOA, spi_nss); 
SPI_I2S_SendData (SPIx, addr); / / 0xf014 >> 2 


while (SPI_I2S_GetFlagStatus (SPIx, SPI_I2S_FLAG_TXE) == RESET); 
SPI_I2S_SendData (SPIx 0x0); 


while (SPI_I2S_GetFlagStatus (SPIx, SPI_I2S_FLAG_RXNE) == RESET); 
SPI_I2S_ReceiveData (SPIx); 


while (SPI_I2S_GetFlagStatus (SPIx, SPI_I2S_FLAG_TXE) == RESET); 
GPIO_SetBits (GPIOA, spi_nss); 

while (SPI_I2S_GetFlagStatus (SPIx, SPI_I2S_FLAG_RXNE) == RESET); 
the value = SPI_I2S_ReceiveData (SPIx); 


return value; 
} 

Write function 


void spi_write (SPI_TypeDef * SPIx, uint32_t addr, uint16_t value) 
{ 


The uint16_t spi_nss; 


uint32_t level; 


if (SPI1 == SPIx) 
spi_nss = SPI1_PIN_NSS; 
else if (SPI2 == SPIx) 
spi_nss = SPI2_PIN_NSS; 



while (SPI_I2S_GetFlagStatus (SPIx, SPI_I2S_FLAG_TXE) == RESET); 
GPIO_ResetBits (GPIOA, spi_nss); 
SPI_I2S_SendData (SPIx, addr); 


while (SPI_I2S_GetFlagStatus (SPIx, SPI_I2S_FLAG_TXE) == RESET); 
SPI_I2S_SendData (SPIx, value); 


while (SPI_I2S_GetFlagStatus (SPIx, SPI_I2S_FLAG_RXNE) == RESET); 
SPI_I2S_ReceiveData (SPIx); 


while (SPI_I2S_GetFlagStatus (SPIx, SPI_I2S_FLAG_TXE) == RESET); 
GPIO_SetBits (GPIOA, spi_nss); 


while (SPI_I2S_GetFlagStatus (SPIx, SPI_I2S_FLAG_RXNE) == RESET); 
SPI_I2S_ReceiveData (SPIx); 
} 

 Take the write function example only so many design

because if it is the beginning of the function will be the NSS pin is pulled low, and then go Send as follows 

GPIO_ResetBits (GPIOA, spi_nss); 
while (SPI_I2S_GetFlagStatus (SPIx, SPI_I2S_FLAG_TXE) == RESET); 
SPI_I2S_SendData (SPIx, addr); 

This CS low after a period of time (the time there are about 16 clock cycles),

only CLK, this delay will reduce the transmission efficiency of the SPI 

That way before CS Euphrates will soon have clk clock out 

The reason why I wrote twice read it twice instead of reading a written also taking into account the efficiency problem 

If you write once read it again to see a relatively large gap between each data of the waveform is not clk,

that will have to wait a period of time, then transmit a data require a relatively high speed The device is not allowed 

It is worth noting that: 


If the SPI master mode, the GPIO is set to 
NSS is GPIO_Mode_Out_PP 
CLK is GPIO_Mode_AF_PP 
MOSI is GPIO_Mode_AF_PP 
MISO is GPIO_Mode_IN_FLOATING 


If the SPI Slave mode, the GPIO is set to 
NSS is GPIO_Mode_Out_PP 
CLK is GPIO_Mode_IN_FLOATING 
MOSI is GPIO_Mode_IN_FLOATING 
MISO is GPIO_Mode_AF_PP

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值