MicroSD-Kartenleseproblem mit einem STM32-Chip

Ich übe die microSD-Karte auf einer Leiterplatte mit dem STM32F405-Chip. Das Testprogramm wird von STM32CubeMX generiert. Der Code ist sehr einfach zu verstehen.

Das Problem ist, dass beim Öffnen der Datei ein Fehler auftritt. Aber das Seltsame ist, dass, wenn ich den Chip zurücksetze, indem ich den NRST-Pin manuell auf Low ziehe, der Chip neu startet und reibungslos funktioniert.

Irgendeine Ahnung?

/* 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);
Welche Fehler passieren? Bitte beschreiben Sie sie mit viel mehr Details.
Initialisierung des Plattenfehlers im ersten Durchlauf. Nachdem ich den Chip zurückgesetzt habe, kein Problem.
Können Sie dieses Programm in Einzelschritten ausführen (in einem Debugger)? An welcher Leitung genau scheitert es? Befindet sich der STM32F405 auf einem Evaluierungsboard? Wenn ja, welche?
in fopen(), graben Sie hinein, Fehler tritt auf in find_volume(&dj.fs, &path, (BYTE)(mode & ~FA_READ));.
Es besteht die Möglichkeit, dass Ihr Programm an irgendeinem Punkt in der Abfolge der notwendigen Operationen fortfährt, ohne zu prüfen, ob die Karte bereit ist; Wenn Sie die MCU zurücksetzen, hat der zweite Versuch Glück, dass dies der Fall ist. Sie müssen alle SD-Vorgänge durchgehen, um herauszufinden, welcher unsicher ohne Bestätigung fortfährt.
Der Code wurde von cubemx generiert. Bei vielen Schritten tritt der Fehler in errorstate = SD_PowerON (hsd) auf; ; gibt SD_COM_CRC_FAILED zurück.

Antworten (1)

Nach einigem Testen und Suchen habe ich das Problem gefunden. Es handelt sich um einen Fehler in der von cubemx generierten Datei. Hier sind die Einzelheiten.

  1. Paketversion: STM32Cube_FW_F4_V1.13.0, Cubemx 4.16.1. Die von mir getestete uSD-Karte ist 1 GB groß und wurde in Japan hergestellt.
  2. Die Bibliothek für microSD und Datei wird vom Cubemx-Assistenten generiert.
  3. Ich habe die microSD auf dem Chip STM32F405RGT6 getestet. .
  4. Das Problem, mit dem ich konfrontiert war, ist, dass die Initialisierung der SD-Karte immer fehlschlägt, aber alles reibungslos verläuft, wenn ich den Chip zurücksetze (über nrst). Seltsam? Machen Sie die Geschichte kurz. Die Initialisierung der SD-Karte schlägt in der Funktion fehl: SD_PowerON(SD_HandleTypeDef *hsd) mit dem Fehlercode SD_COM_CRC_FAILED. Beachten Sie, dass die Funktion in der Datei definiert ist: stm32f4xx_hal_sd.c
  5. Ich habe HAL_Delay(1) nach clock_enable in der Funktion SD_PowerON verschoben, alles funktioniert gut.

Wenn Sie mehr Details lesen möchten, lesen Sie bitte den Thread: https://community.st.com/thread/34299-microsd-card-problem

Hier ist der Code:

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);