Проблемы со чтением данных с карты microSD

Я пытаюсь прочитать блок данных с карты micro SD стандартной емкости, но полученные данные не имеют никакого смысла. Вот что я делаю:

  • Инициализация карты
  • Чтение данных
    • Установка низкого уровня CS
    • Отправка CMD16 для установки длины блока
    • Отправка CMD17 со стартовым адресом
    • Ожидание стартового байта (0xfe)
    • Получение байтов и вывод их на последовательный терминал
    • Получение CRC
    • Настройка CS на высокий уровень
    • Отправка 8 дополнительных часов (?)

Данные, которые я пытаюсь прочитать, — это загрузочный сектор FAT16, как показано ниже: Содержимое картыИ данные, которые я получаю, следующие:введите описание изображения здесь

В этот момент я даже не могу начать думать о том, что происходит не так. Я не думаю, что это ошибка передачи, потому что данные всегда одни и те же. Я также могу каждый раз читать подпись загрузочного сектора 0x55 0xAA, даже если я установил начальный адрес на 510 и прочитал два байта, они возвращаются отлично. Проблема в том, что я не могу прочитать другие байты.

Я также пробовал менять карты местами, и это тоже не помогло.

Что мне не хватает?

РЕДАКТИРОВАТЬ: рассматриваемая функция ниже.

bit sd_read_block(unsigned long size, unsigned long start_addr)
{
    unsigned long i;
    unsigned char r;

    SD_CS = 0;

    r = sd_card_cmd(16, size, 0);

    sprintf(usb_uart_tx_buffer, "CMD16 R Token: %02x.\r\n", r);
    usb_uart_tx(usb_uart_tx_buffer);

    r = sd_card_cmd(17, start_addr, 0);

    sprintf(usb_uart_tx_buffer, "CMD17 R Token: %02x.\r\n", r);
    usb_uart_tx(usb_uart_tx_buffer);

    // wait for start token
    r = 0;
    while (spi_rx_byte() != 0xfe) {
        if (r++ > 25) {
            SD_CS = 1;
            return r;
        }
    }

    for (i = 0; i < size; i++) {
        if (i % 20 == 0) {
            UART1_TX(0x0d);
            UART1_TX(0x0a);
        }
        sprintf(usb_uart_tx_buffer, "%02x ", spi_rx_byte());
        usb_uart_tx(usb_uart_tx_buffer);
    }

    // CRC
    spi_rx_byte();
    spi_rx_byte();

    // extra clocks
    r = spi_rx_byte();

    SD_CS = 1;

    return 0;
}
Я не могу точно сказать, что происходит, но, похоже, размер байта неверен, так как в fat16 используется другой размер, чем в fat32/ntfs. Все 00 в начале не имеют смысла. а потом кажется, что некоторые байты отсутствуют/сжаты? что-то не так с тем, как байты принимаются/интерпретируются.

Ответы (1)

Получается, что я читал MBR, которая находится по адресу 0на SD-карте. Чтобы найти расположение загрузочного сектора, нужно прочитать соответствующую запись в MBR. Записи начинаются с адреса 0x01beи имеют размер 16 байт каждый. Точка интереса в записи находится по смещению 0x08, имеет длину 4 байта и называется LBA. [Википедия] Чтобы получить адрес расположения загрузочного сектора, нужно умножить LBA на размер сектора (512 байт). [Форум Микрочипа]

Например:

В приведенном выше выводе четыре записи выглядят так:

00 02 10 00 06 2f ef af 8d 00 00 00 73 0f 3a 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Как видите, используется только одна запись. LBA в этом случае имеет 8d 00 00 00и находится в формате с прямым порядком байтов, поэтому в формате с прямым порядком байтов это будет 0x8dили 141 в десятичном формате. Умножьте это на 512, и вы получите 72192 ( 0x11a00). Это адрес сектора, где начинается FAT.