Problemas al leer datos de una tarjeta microSD

6

Estoy intentando leer un bloque de datos de una tarjeta micro SD de capacidad estándar, pero los datos recibidos no tienen ningún sentido. Esto es lo que estoy haciendo:

  • Inicializando la tarjeta
  • datos de lectura
    • configurando CS bajo
    • Enviando CMD16 para establecer la longitud del bloque
    • Enviando CMD17 con dirección de inicio
    • Esperando el byte de inicio (0xfe)
    • Recibiendo bytes e imprimiéndolos en el terminal serial
    • recibiendo CRC
    • Configurar CS alto
    • Enviando 8 relojes extra (?)

Los datos que trato de leer son el sector de arranque FAT16, como se muestra a continuación: Ylosdatosqueestoysacandosonestos:

En este punto, ni siquiera puedo empezar a pensar en lo que está mal. No creo que sea un error de transmisión, porque la salida de datos es siempre la misma. También puedo leer la firma del sector de arranque 0x55 0xAA cada vez, incluso si configuro la dirección de inicio en 510 y leo dos bytes, vuelven perfectamente. El problema es que no puedo leer otros bytes.

También intenté intercambiar tarjetas y eso tampoco ayudó.

¿Qué me estoy perdiendo?

EDITAR: la función en cuestión está abajo.

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;
}
    
pregunta Armandas

1 respuesta

10

Resulta que estaba leyendo el MBR, que se encuentra en la dirección 0 en la tarjeta SD. Para encontrar la ubicación del sector de arranque, es necesario leer la entrada correspondiente en el MBR. Las entradas comienzan en la dirección 0x01be y tienen 16 bytes cada una. El punto de interés en la entrada se encuentra en el offset 0x08 , tiene una longitud de 4 bytes y se denomina LBA. [Wikipedia] Para obtener la dirección de la ubicación del sector de inicio, se multiplicaría el LBA por el tamaño de un sector (512 bytes). [foro de microchip]

Por ejemplo:

En la salida anterior, las cuatro entradas se ven así:

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

Como puede ver, solo se usa una entrada. El LBA en este caso es 8d 00 00 00 y está en formato little-endian, por lo que en big-endian sería 0x8d o 141 en decimal. Multiplica esto por 512 y obtienes 72192 ( 0x11a00 ). Esta es la dirección del sector donde comienza el FAT.

    
respondido por el Armandas

Lea otras preguntas en las etiquetas