Запись и чтение флеш-памяти через SPI

Я впервые пытаюсь использовать протокол 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 для фактического получения данных?

Спасибо!


person Gui W. Eckert    schedule 10.01.2014    source источник


Ответы (1)


SPI - это полнодуплексная двунаправленная шина, по которой данные одновременно отправляются на ведомое устройство и принимаются от ведомого устройства. Ваш контроллер SPI не знает, принадлежит ли данный байт ведущему устройству, ведомому устройству или обоим. Следовательно, всякий раз, когда вы отправляете байт, вы также должны читать байт, хотя бы для того, чтобы выбросить его. Точно так же вы не можете получить байт, не отправив байт, даже если ведомое устройство выбросит его.

Взгляните на Википедию.

Итак, ваш код делает

  1. Отправка Read_ID подчиненному.
  2. Чтение и отбрасывание байта, одновременно считанного из ведомого.
  3. Запишите 0 ведомому устройству, чтобы ведомое устройство могло отправить байт данных.
  4. Прочтите байт данных, который был одновременно считан с ведомого устройства.
  5. Вернитесь к # 3.

Кстати, такие вопросы лучше подходят для EE Stack Exchange, поскольку это больше касается аппаратного протокола, а не программирования.

person DoxyLover    schedule 11.01.2014