Problema de lectura de tarjeta MicroSD con un chip STM32

Estoy practicando la tarjeta microSD en una placa PCB con el chip STM32F405. El programa de prueba es generado por STM32CubeMX. El código es muy fácil de entender.

El problema es que ocurre un error cuando se abre el archivo. Pero lo extraño es que si restablezco el chip tirando del pin NRST a nivel bajo manualmente, el chip se reinicia y funciona sin problemas.

¿Cualquier pista?

/* Reset of all peripherals, initializes the flash interface, and the Systick. */
HAL_Init();

/* Configure the system clock */
SystemClock_Config();

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_SDIO_SD_Init();
MX_TIM9_Init();
//MX_FATFS_Init();  // We call FATFS_LinkDriver directly to initialize the fatfs
MX_USB_DEVICE_Init();
TimeDelay_Init();


/* USER CODE BEGIN 2 */

GREEN_LED_ON;RED_LED_ON;
TM_DelayMillis(500);
GREEN_LED_OFF;RED_LED_OFF;
TM_DelayMillis(1000);


/* USER CODE BEGIN 2 */

// Before it starts,  wait for computer to connect
while(SHIFT_BUTTON==1){ // Wait for the shift button to be pushed
    ;
}

/* USER CODE END 2 */


/* Infinite loop */

/* USER CODE BEGIN WHILE */
FRESULT res;                                           /* FatFs function common result code */
uint32_t byteswritten, bytesread, byteswrittentotal;   /* File write/read counts */
uint8_t rtext[200];
char textbuf[200]; //string buffer
char filename[]="fileW4.txt"; // Filename length should be <= 8   /* File read buffer */


/* ##-1- Link the microSD disk I/O driver ################################## */
if(FATFS_LinkDriver(&SD_Driver, SD_Path) == 0) // We call FATFS_LinkDriver directly to initialize the fatfs
{
    sprintf(usbbuffer, "\n---FATFS_LinkDriver OK ---\n");//export it to char buffer first.
    SendTextMsgToUSB(usbbuffer); // Send the txt back

    /* ##-2- Register the file system object to the FatFs module ############## */
    if(f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0) != FR_OK)
    {
        /* FatFs Initialization Error */
        sprintf(usbbuffer, "\n---f_mount error ---\n"); // Export it to char buffer first.
        SendTextMsgToUSB(usbbuffer);  // Send the txt back

        Error_Handler();
    }
    else
    {
        /* ##-3- Create a FAT file system (format) on the logical drive ######### */
        /* WARNING: Formatting the uSD card will delete all content on the device */
        //   if(f_mkfs((TCHAR const*)SDPath, 0, 0) != FR_OK) // No need to format, so comment it
        //f_mkfs((TCHAR const*)SDPath, 0, 0);
        sprintf(usbbuffer, "\n---ready to open file ---\n"); // Export it to char buffer first.
        SendTextMsgToUSB(usbbuffer); // Send the txt back

        /* ##-4- Create and Open a new text file object with write access ##### */
        res=f_open(&MyFile, filename, FA_CREATE_ALWAYS | FA_WRITE);
        if (res!= FR_OK)
        {
            /* 'STM32.TXT' file Open for write Error */
            sprintf(usbbuffer, "\n---Open file error ---\n");//export it to char buffer first.
            SendTextMsgToUSB(usbbuffer);  //send the txt back

            Error_Handler();
        }
        else
        {
            /* ##-5- Write data to the text file ################################ */
            sprintf(usbbuffer, "\n---File is open. Ready to write contents ---\n"); // Export it to char buffer first.
            SendTextMsgToUSB(usbbuffer);  // Send the txt back

            // Write capacity info as testing
            BSP_SD_GetCardInfo(&uSdCardInfotmp);
            sprintf(textbuf, "\nThe capacity of the card is:%"PRIu64"B\nThis is for file:%s", uSdCardInfotmp.CardCapacity,filename); // Export it to char buffer first. In this way, no null symbol
            res=f_write(&MyFile, textbuf, strlen(textbuf), (void *)&byteswritten);
            if((byteswritten == 0) || (res != FR_OK))
            {
                /* 'STM32.TXT' file Write or EOF Error */
                Error_Handler();
            }
            sprintf(usbbuffer, "\n---First line was written %s ---\n", textbuf); // Export it to char buffer first.
            SendTextMsgToUSB(usbbuffer);  // Send the txt back

            // Now we test the fast file writing of small bytes.
            unsigned char testtimer=0;
            for(int i=0; i<20000; i++)
            {
                sprintf(textbuf, "i=%d,data=%d\n", i, i); // Export it to char buffer first.
                uint32_t bytecount=MyWriteToFile(&MyFile, textbuf, strlen(textbuf));
                byteswritten += bytecount;
                if(bytecount==0){
                    f_close(&MyFile);Error_Handler();
                }
            }
            byteswritten += MyFlushDatatoFile(&MyFile); // Close file

            f_close(&MyFile);
            sprintf(usbbuffer, "\n---File is closed ---\n"); // Export it to char buffer first.
            SendTextMsgToUSB(usbbuffer);  // Send the txt back

            GREEN_LED_ON;
        }
    }
}

/* ##-11- Unlink the RAM disk I/O driver #################################### */
FATFS_UnLinkDriver(SD_Path);
¿Qué errores suceden? Por favor, descríbalos con muchos más detalles.
inicialización del error de disco en la primera ejecución. Después de restablecer el chip, no hay ningún problema.
¿Puedes hacer un solo paso de este programa (en un depurador)? ¿Exactamente en qué línea está fallando? ¿Está el STM32F405 en una placa de evaluación? ¿Si sí, cual?
en fopen(), profundice en él, ocurre un error en find_volume(&dj.fs, &path, (BYTE)(mode & ~FA_READ));.
Lo más probable es que, en algún momento de la secuencia de operaciones necesarias, su programa avance sin verificar que la tarjeta esté lista; cuando reinicia la MCU, el segundo intento tiene suerte. Deberá pasar por todas las operaciones SD para averiguar cuál está procediendo de manera insegura sin confirmación.
El código ha sido generado por cubemx. con muchos pasos, el error ocurre en errorstate = SD_PowerON(hsd); ; devuelve SD_COM_CRC_FAILED.

Respuestas (1)

Después de algunas pruebas y búsquedas, encontré el problema. Es un error en el archivo generado por cubemx. Aquí están los detalles.

  1. Versión del paquete: STM32Cube_FW_F4_V1.13.0, Cubemx 4.16.1. La tarjeta uSD que probé es de 1 GB fabricada en Japón.
  2. El asistente de cubemx genera la librería para microSD y el archivo.
  3. Probé la microSD en el chip STM32F405RGT6. .
  4. El problema que enfrenté es que la inicialización de la tarjeta SD siempre falla, pero todo funciona sin problemas si reinicio el chip (a través de nrst). ¿Extraño? Haz la historia corta. La inicialización de la tarjeta SD falla en la función: SD_PowerON(SD_HandleTypeDef *hsd) con el código de error SD_COM_CRC_FAILED. Tenga en cuenta que la función está definida en el archivo: stm32f4xx_hal_sd.c
  5. Moví HAL_Delay(1) después de clock_enable en la función SD_PowerON, todo funciona bien.

Si desea leer más detalles, lea el hilo: https://community.st.com/thread/34299-microsd-card-problem

Aquí está el código:

static HAL_SD_ErrorTypedef SD_PowerON(SD_HandleTypeDef *hsd)
{
  SDIO_CmdInitTypeDef sdio_cmdinitstructure; 
  __IO HAL_SD_ErrorTypedef errorstate = SD_OK; 
  uint32_t response = 0U, count = 0U, validvoltage = 0U;
  uint32_t sdtype = SD_STD_CAPACITY;

  /* Power ON Sequence -------------------------------------------------------*/
  /* Disable SDIO Clock */
  __HAL_SD_SDIO_DISABLE(); 

  /* Set Power State to ON */
  SDIO_PowerState_ON(hsd->Instance);

 /* 1ms: required power up waiting time before starting the SD initialization 
 sequence */
 // HAL_Delay(1); //should be after __HAL_SD_SDIO_ENABLE()

 /* Enable SDIO Clock */
 __HAL_SD_SDIO_ENABLE();
//moved to here
 /* 1ms: required power up waiting time before starting the SD initialization 
 sequence */
 HAL_Delay(1);