Estoy haciendo, por primera vez, la interfaz entre un microcontrolador (PIC32MX) y una tarjeta microSD a través de SPI. Las tarjetas que estoy usando se están inicializando correctamente. El tamaño del sector / bloque se fija en 512 bytes / sector porque solo usaré tarjetas SDHC y SDXC. Estoy escribiendo / escribiendo en la tarjeta, porque para mi aplicación no necesito un sistema de archivos, es un registrador de datos simple. Puedo verificar el contenido de los sectores de la tarjeta con el software "Hex Workshop Hex Editor". El reloj SPI se encuentra actualmente en 200 KHz para un punto de partida.
Tengo una función que escribe un sector completo y una función que lee un sector completo. He notado que si uso la función sector_write con CMD24 (WRITE_BLOCK) para al menos una vez (y funciona en la primera llamada, escribiendo el sector correctamente), las siguientes llamadas sector_write no funcionarán. Siempre veo 0 almacenados en el segundo sector en el que quiero escribir. En este ejemplo, estoy tratando de llenar el sector 1000 y 1300 con el mismo contenido, pero solo el sector 1000 se llena con ese contenido, y el sector 1300 se llena con 0 (en realidad es su contenido original). Además, he intentado escribir en una secuencia los sectores 1000 y 1001 y el resultado es el mismo (el sector 1001 no se llena con el mismo contenido del sector 1000).
Es decir, si llamo a la función sector_escritura una vez , la función de lectura devuelve lecturas de un sector lleno de 0 (incorrecto). Si comento todas las llamadas de write_sector, las lecturas se realizan correctamente.
Para el siguiente código, solo se escribe el sector 1000 ... todo el sector 1300 permanece en 0s. Este código está justo después de que la tarjeta se haya inicializado correctamente con las respuestas correctas de la tarjeta.
para la inicialización yo uso: | CMD0 | CMD8 | CMD58 | repitió CMD55 + ACMD41 | CMD58 |. No uso CMD16 ...
¿Qué puedo hacer para resolver esto? ¿Alguien aquí ya ha enfrentado este problema? Saludos.
if (SD_initialized == true)
{
write_reply = SD_write_sector(1000);
DelayMs(1000);
write_reply = SD_write_sector(1300);
}
uint8_t SD_command[6];
uint8_t SD_write_buff[512];
uint8_t SD_read_buff[512];
uint8_t n = 0;
for (i=0; i<512; i++)
{
SD_write_buff[i] = n;
n++;
}
if (SD_initialized == true)
{
write_reply = SD_write_sector(1000);
DelayMs(1000);
write_reply = SD_write_sector(1300);
}
uint8_t SPI_write (uint8_t byte)
{
while(SPI1STATbits.SPITBF);
SPI1BUF = byte;
while(!SPI1STATbits.SPIRBF);
return SPI1BUF;
}
uint8_t SD_write_sector (uint32_t sector) //sector = block number
{
uint8_t reply;
uint32_t i;
do
{
reply = SD_send_cmd (24, sector);
}
while (reply != 0);
SPI_write(0xFF); //Dummy byte
SPI_write(0xFE); //Data start token (0xFE)
for(i=0; i<512; i++) //Data block
{
SPI_write(SD_write_buff[i]);
}
SPI_write(0xFF); //2 bytes of CRC
SPI_write(0xFF);
reply = SPI_write(0xFF);
reply &= 0x1F; // Response of SD: xxx0sss1
// sss = 010 ---> Data accepted = 0x05
// sss = 101 ---> Data rejected due to CRC error = 0x0B
// sss = 110 ---> Data rejected due to writing error = 0x0D
return reply;
}
uint8_t SD_send_cmd (uint8_t CMD, uint32_t ARG)
{
SD_command[0] = CMD + 0x40;
SD_command[1] = ARG >> 24;
SD_command[2] = ARG >> 16;
SD_command[3] = ARG >> 8;
SD_command[4] = ARG & 0xFF;
SD_command[5] = getCRC7 (SD_command, 5);
SPI_write (SD_command[0]);
SPI_write (SD_command[1]);
SPI_write (SD_command[2]);
SPI_write (SD_command[3]);
SPI_write (SD_command[4]);
SPI_write (SD_command[5]);
SD_reply1 = SPI_write(0xFF); //dummy read
SD_reply1 = SPI_write(0xFF); //actual read
if (CMD == 8 || CMD == 58)
{
SD_reply2 = SPI_write(0xFF);
SD_reply3 = SPI_write(0xFF);
SD_reply4 = SPI_write(0xFF);
SD_reply5 = SPI_write(0xFF);
}
return SD_reply1;
}
uint8_t SD_read_sector (uint32_t sector)
{
uint8_t reply;
uint32_t i;
reply = SD_send_cmd (17, sector);
if (reply != 0) { return reply; }
while (SPI_write(0xFF) != 0xFE); //SPI return read byte
for (i=0;i<512;i++)
{
SD_read_buff[i] = SPI_write(0xFF);
}
SPI_write(0xFF); //read 16-bit CRC
SPI_write(0xFF);
return reply;
}