c - 通过 SPI 写入和读取闪存

标签 c memory spi cortex-m flash-memory

第一次尝试使用SPI协议(protocol)。我试图理解我的开发工具包(它有一个 STM32F207VCT6 微 Controller )附带的示例代码。这段代码实现了与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 字节才能实际接收数据?

谢谢!

最佳答案

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

看看Wikipedia .

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

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

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

关于c - 通过 SPI 写入和读取闪存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21050359/

相关文章:

c - 按地址返回

c - 为什么 int 在 c 或任何其他语言中占用 4 个字节?

c++ - CUDA:处理不同大小的数组

python - 列出内存使用情况

常量与静态常量

c++ - 从 Arduino 到 Raspberry Pi 的不可靠 SPI 字节数组传输

c - 如何从ATmega32中的软件SPI读取32位变量?

c - 我在这个循环中做错了什么?

c++ - 使用 GetModuleHandle 获取指向 IMAGE_DOS_HEADER 的指针?

c++ - Unix 读取缓冲区参数