1

这是我第一次尝试使用 SPI 协议。我正在尝试理解我的开发套件(具有 STM32F207VCT6 微控制器)附带的示例代码。此代码实现与 AT45DB041D 闪存的通信(读取和写入)。

每次此示例代码设法读取内存时,它不仅会发送有关要读取的内容的信息,还会要求立即接收数据。收到的这些数据不用于任何目的(显然)。稍后接收命令将通过先发送 0x00 字节再次询问要读取的实际数据。以下代码表明:

void AT45DBXX_Read_ID(u8 *IData){
u8 i;
AT45DBXX_BUSY();
AT45DBXX_Enable;  //Chip Select drive to low
SPIx_Send_byte(Read_ID);        
for(i=0;i<4;i++)
{
    IData[i] = SPIx_Receive_byte();
}
AT45DBXX_Disable; //Chip Select drive to high
}

定义:

void SPIx_Send_byte(u16 data){
while(SPI_I2S_GetFlagStatus(Open207V_SPIx, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open207V_SPIx,data);

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

u16 SPIx_Receive_byte(void){
while(SPI_I2S_GetFlagStatus(Open207V_SPIx, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open207V_SPIx,0x00);

while(SPI_I2S_GetFlagStatus(Open207V_SPIx, SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(Open207V_SPIx);
}

如您所见,SPIx_Send_byte 代码不仅发送要读取的内容,还接收不会使用的信息。

有人可以帮我理解为什么需要这样做以及为什么需要发送 0x00 字节来实际接收数据吗?

谢谢!

4

1 回答 1

2

SPI 是一种全双工双向总线,其中数据同时发送到从机并从从机接收。您的 SPI 控制器不知道给定字节是来自主设备还是来自从设备,或两者都是 glong。因此,每当您发送一个字节时,您也必须读取一个字节,即使只是将其丢弃。同样的道理,你不能在不发送字节的情况下接收到一个字节,即使从机会丢弃它。

看看维基百科

所以,你的代码正在做的是

  1. 将 Read_ID 发送到从站。
  2. 读取和丢弃从机中同时读取的字节。
  3. 向从机写入0,使从机能够发送一个字节的数据。
  4. 读取同时从从机读取的数据字节。
  5. 循环回到#3。

顺便说一句,这样的问题更适合EE Stack Exchange,因为它更多的是关于硬件协议而不是编程。

于 2014-01-11T03:47:48.430 回答