2016-02-25 2 views
1

Я пишу и читаю значения на SD-карте в режиме SPI. Частота для блоков записи и чтения по 512 байт установлена ​​в 10 МГц. Для записи блока требуется около 5 мс, а время между блоками составляет около 10 мс.microSD-карта в режиме SPI времени

Есть ли способ улучшить скорость написания?

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); 
} 
+0

Пожалуйста, покажите код, который вы используете для это считывание/вписывание. Трудно вам помочь без этого. – 4pie0

+1

К сожалению, SD-карты, как известно, медленны при записи в любом случае, независимо от того, что вы делаете с интерфейсом :( –

ответ

1

Вы не можете, по крайней мере, не сильно. Причина в том, что сам режим SPI является узким местом. Таким образом, вы можете использовать несколько трюков здесь и там, чтобы получить эту скорость, но вы действительно не будете очень полезны. Я бы посоветовал вам использовать SDIO, если вам действительно нужна такая скорость (это не так сложно, как вы думаете). Если вы используете AVR, попробуйте линейку xmega (не цитируйте меня на этом, я не совсем осведомлен в AVR, так как я использую ARM) или полностью переключаюсь на другую линейку.

+0

Я на самом деле использую SAM D21G ARM cortex M0 +. Любое направление будет замечательным, так как я потратил много усилий, записи и чтения в режиме SPI. –

+0

@Shahe Ansar Это не обязательно, если есть неэффективность в коде OP, написанная и может быть исправлена. – 4pie0

+0

@MoldovanAlex Как я уже сказал, я не совсем осведомлен о продуктах Atmel. Но если это M0 +, он должен иметь возможность делать SDIO. Просто используйте это. –

0

Для того, чтобы получить высокие скорости записи, вам необходимо:
- использовать более быстрые часы
- использовать более широкую шину
- Напишите большие блоки (2k или 4k) в то время

В других слов, вам очень нужно использовать спецификацию SDIO.

Есть также способы начать большую последовательную транзакцию, а не завершить ее до тех пор, пока все данные не будут получены (но, возможно, это в спецификации SDIO, а не в интерфейсе командной строки SPI). Эти подсказки подсказывают контроллеру, что он может подготовить большую часть флэш-памяти и не передавать буфер записи до тех пор, пока он не будет заполнен.

И даже тогда вы можете в конечном итоге «очень долго» писать циклы время от времени, поэтому вы не можете полагаться на SD-карту для передачи высокоскоростных данных в реальном времени без буферов на вашей стороне для обработки латентных всплесков.

0

Вы должны выложили свой spi_write_buffer_wait код, но рассмотреть что-то вроде этого:

Rearange вещи в вашей фактической функции записи, где вы отправляете данные. Думаю об этом. Вам нужно подождать, пока 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 ...

Если вы собираетесь написать более 512bytes данных, рассмотрите возможность использования мультиблок пишет (4k блоки, например сразу).

Обычно SD-карты имеют внутренний размер блока более 512 байт. Итак, чтобы записать 512 байт, они должны внутренне читать, например, 4k, обменивать ваши 512 байт и записывать все обратно ... так что написать больше данных сразу - это всегда хорошая идея ...

Смежные вопросы