簡體   English   中英

SPI模式下的microSD卡時序

[英]microSD card in SPI mode timing

我正在SPI模式下在SD卡上寫入和讀取值。 寫入和讀取512字節塊的頻率設置為10Mhz。 寫入一個塊大約需要5毫秒,塊之間的時序大約是10毫秒。

有什么辦法可以提高寫作速度?

void sd_card_write_block(uint16 blockNumber, uint8* buffer)
{
  uint16 blockLow = 0;
  uint16 blockHigh = 0;
  uint8 dummy = 0;
  uint8 result = 0;
  uint8 data_block_start_byte = 0;
  uint8 write_command[SD_CMD_SIZE] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  uint8 dummy_buffer[DUMMY_BUFFER_LENGTH] = {0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF};
  uint8 i = 0;
  uint8 check_response[CHECK_RESPONSE_SIZE] = {0x00, 0x00, 0x00};
  uint8 check_response1[CHECK_RESPONSE_SIZE] = {0x00, 0x00, 0x00};
  uint8 r1 = 0;
  uint16 retry = 0;
  uint8 response1 = 0;

  dummy = 0xFF;
  //initialize the dummy buffer to keep MOSI pin High
  for(i = 0; i < DUMMY_BUFFER_LENGTH; i++)
  {
    dummy_buffer[i] = 0xFF;
  }

  //set CS pin low
  spi_select_slave( &spi_master_instance, &slave, true);

  //send three clock cycles with MOSI HIGH (Ncs)
  spi_write_buffer_wait( &spi_master_instance, dummy_buffer, NCS_LENGTH);

  //block size was set in sd_init
  blockLow = ((blockNumber & 0x003F) << 9);
  blockHigh = ((blockNumber & 0xFFC0) >> 7);

  //send SD CMD24(WRITE_SINGLE_BLOCK) to write the data to SD card
  write_command[0] = 0x58;

  //high block address bits, blockHigh HIGH and LOW
  write_command[1] = (blockHigh >> 0x08);

  write_command[2] = (blockHigh & 0xFF);
  //low block address bits, blockLow HIGH and LOW
  write_command[3] = (blockLow >> 0x08);
  write_command[4] = (blockLow & 0xFF);

  //checksum is no longer required but send 0xFF
  write_command[5] = 0xFF;

  spi_write_buffer_wait( &spi_master_instance, write_command, SD_CMD_SIZE);


  spi_transceive_buffer_wait( &spi_master_instance, dummy_buffer, check_response, CHECK_RESPONSE_SIZE);

  //send three clock cycles with MOSI High
  spi_write_buffer_wait( &spi_master_instance, dummy_buffer, DUMMY_BUFFER_LENGTH);

  //set bit 0 to 0 which indicates the beginning of the data block
  data_block_start_byte = DATA_BLOCK_START_TOKEN;
  spi_transceive_buffer_wait( &spi_master_instance, &data_block_start_byte, &result, SD_RESPONSE_SIZE);


  /*takes so long because its similar to transreceivea and it discards the rx*/
  spi_write_buffer_wait( &spi_master_instance, buffer, SD_BLOCK_LENGTH);


  //read the microSD card response
  spi_transceive_buffer_wait( &spi_master_instance, dummy_buffer, check_response1, CHECK_RESPONSE_SIZE);

  do
   {
     // write dummy byte
     spi_transceive_buffer_wait( &spi_master_instance, &dummy, &response1, SD_RESPONSE_SIZE);

     r1 = response1;
     // do retry counter
     retry++;
     if(retry > MAX_TIMEOUT)
     {
       spi_select_slave( &spi_master_instance, &slave, false);
       break;
     }
   }
   while(r1 == END_OF_BLOCK_RESPONSE);
  //set the CS High
  spi_select_slave( &spi_master_instance, &slave, false);
}

您不能,至少沒有太多。 原因是SPI模式本身是瓶頸。 因此,您可以在此處和此處使用一些技巧來加快速度,但實際上並不會從中獲益良多。 如果您確實需要這么快的速度,我建議您使用SDIO(它並不像您想象的那么復雜)。 如果您使用的是AVR,請嘗試使用xmega陣容(不要在此引用我,因為我使用的是ARM,因此我對AVR的了解並不多),或完全切換到另一個陣容。

為了獲得較高的寫入速度,您需要:
-使用更快的時鍾
-使用更寬的巴士
-一次寫入較大的塊(2k或4k)

換句話說,您非常需要使用SDIO規范。

還有一些方法可以開始一個大型的順序事務,直到接收到所有數據后才結束它(但也許是在SDIO規范中,而不是在SPI命令接口中)。 這些提示告訴控制器它可以准備閃存的很大一部分,並且在閃存寫滿之前不提交寫入緩沖區。

即使這樣,您有時仍可能會遇到“非常長”的寫周期,因此,您不能依靠SD卡實時流式傳輸高速數據,而無需使用緩沖區來處理延遲現象。

您應該已經發布了spi_write_buffer_wait代碼,但請考慮以下內容:

在實際的寫入功能中重新安排發送數據的位置。 想一想。 您必須等到SD卡指示您該字節已成功寫入。 使用這個“無用的”等待時間來准備下一個數據。

/* write a single block */
for ( i = MMC_BLOCKLEN; i > 0; i-- ) {
    uint8_t data = *buffer;
    buffer++;
    wait_till_send_done();
    xmit_byte ( data );
}
wait_till_send_done();

在開始等待SD卡指示其已成功寫入一個字節之前,在那里准備發送字節,還將指針向前移動一個字節。

檢查生成的ASM代碼也是一個好主意...

如果要寫入超過512字節的數據,請考慮使用多塊寫入(例如一次寫入4k塊)。

通常,SD卡的內部塊大小大於512字節。 因此要寫入512字節,他們必須在內部讀取例如4k,交換512字節並將所有內容寫回……因此一次寫入更多數據始終是一個好主意……

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM