这是我第一次尝试使用SPI协议。我试图理解我的开发工具包(它有一个STM32F207VCT6微控制器)附带的示例代码。该代码使用AT45DB041D闪存实现通信(读写)。
每次这个示例代码设法读取内存时,它不仅会发送有关要读取的内容的信息,还会要求接收数据。收到的这些数据不会用于任何目的(显然)。稍后将通过先发送0x00字节的receive命令再次询问要读取的实际数据。以下代码显示:
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字节来实际接收数据?
谢谢!
答案 0 :(得分:2)
SPI是一种全双工双向总线,数据既可以发送到从器件,也可以从器件同时接收。您的SPI控制器不知道给定字节是来自主设备,还是来自从设备,或两者都是。因此,无论何时发送一个字节,您还必须读取一个字节,如果只是扔掉它。出于同样的原因,即使从属设备将其丢弃,也不能在不发送字节的情况下接收字节。
看看Wikipedia。
所以,你的代码正在做什么
顺便说一下,这些问题更适合the EE Stack Exchange,因为它更多地是关于硬件协议而不是编程。