Interface SD CARD with SDIO in STM32

I already covered How to use SD card in STM32 using SPI. You can check that out HERE.
Today in this tutorial, we will interface the SD CARD using SDIO in STM32. Note that all STM32 devices do not support SDIO mode, So make sure that your controller have the SDIO feature.

CubeMX Setup

We will start by setting up the CubeMx first. So select the SDIO and than select 4 bit bus, and leave everything else unchanged. If you get FR_DISK_ERROR, than increase the SDIOCLK divide factor in the picture below

sdio setup

Next, select the FATFS, and than select SD CARD. I am leaving everything to default.

fatfs setup

Now open the project and copy file_handling.c, file_handling.h, files in the project folder.

Some insight into the code

You can check the functions used in the file_handling.h file. Some of those functions are discussed below.

/* mounts the sd card*/
void Mount_SD (const TCHAR* path);

/* unmounts the sd card*/
void Unmount_SD (const TCHAR* path);

As the name suggests, they are used for mounting and un-mounting the SD CARD

/* Start node to be scanned (***also used as work area***) */
FRESULT Scan_SD (char* pat);

Scan for the files and directories present in the SD CARD from the path input in the argument. It sends the details directly to the UART.

/* creates a directory
 * @ name: is the path to the directory
FRESULT Create_Dir (char *name);

Creates the directory in the input path, entered in the argument. For example Create_Dir ("/dir1"); will create a directory named dir1 in the root of the SD CARD itself.

/* Removes the file from the sd card
 * @ name : is the path to the file*/
FRESULT Remove_File (char *name);

Removes the file or the directory, whose name and path is in the argument. Note that directory can only be removed, if it is empty. For example Remove_File("/FILE.TXT"); removes the FILE.TXT from the root of the SD CARD.

/* creates the file, if it does not exists
 * @ name : is the path to the file*/
FRESULT Create_File (char *name);

Creates a file, (name and path is in the argument), at the entered path in the SD CARD. If the file already exists, it will return an error. For example Create_File("file1.txt"); will create a file named file1.txt in the root directory.

/* read data from the file
 * @ name : is the path to the file*/
FRESULT Read_File (char *name);

/* write the data to the file
 * @ name : is the path to the file*/
FRESULT Write_File (char *name, char *data);

/* updates the file. write pointer is set to the end of the file
 * @ name : is the path to the file
FRESULT Update_File (char *name, char *data);

are used to Read, Write, and Update data to the file. These functions will output the result of each operation to the Uart.

main function


Above, I am mounting the SD card, and than formatting it to remove any file present in the root directory. It can’t remove directories right now
I have created 2 files. These are empty right now, and i will update the data later in the code.

sprintf(buffer, "Hello ---> %d\n", indx);
Update_File("FILE1.TXT", buffer);
sprintf(buffer, "world ---> %d\n", indx);
Update_File("FILE2.TXT", buffer);



As you can see above, the data in the files will keep updating every 2 seconds.


file data
uart output

Check out the Video Below


You can help with the development by DONATING
To download the code, click DOWNLOAD button and view the Ad. The project will download after the Ad is finished.

34 Comments. Leave new

  • Does it still works? I am using custom f401 and in that f_mount() function takes a long time or forever and never progresses.

  • sanket awasthy
    October 27, 2023 4:08 PM

    I am currently working on a project that involves integrating USB functionality for data transfer and data logging on an STM32F407VG micro-controller. Specifically, I want to log data files on an SD card and enable the user to download these logged files from the SD card via USB. Additionally, I’d like to allow users to copy files from their PC to the SD card via USB, all through the STM32F407VG using the SDIO communication protocol.

    I’m facing a challenge in making the USB_OTG_FS (On-The-Go Full Speed USB) and the SD card (using FatFS) work together seamlessly. I would greatly appreciate your guidance and any insights you might have on how to achieve this integration.

    Here are some specific questions I have:

    How do I configure USB_OTG_FS as a USB Device in STM32CubeMX or other development tools?
    What are the essential initialization and setup steps for using the USB_OTG_FS as a USB Device alongside the FatFS library for SD card communication?
    Are there any sample code snippets or project examples that demonstrate this integration?
    What should I be mindful of when managing the data transfer between the USB and SD card to avoid conflicts or data corruption?

  • Hi Sir,
    I m Using STM32 and storing in sd card using fatfs library, it is working fine. Now I want to fetch the data of the sd card using usb in device mode from the stm, but usb-device and fatfs are conflicting and I m not able to fetch data.
    If I turn off fatfs, then usb-device works, but with fatfs usb-device doesn’t work.

    Can you guide pls

  • I’m constantly getting FR_NOT_READY error when f_mount on my STM32F103RCT Board. Does the Clock settings matters?

  • Hello, thanks for grate tutorials. 
    I want to read data on USART and save them in a buffer and then store them on SD-card. and my data have different size. I used codes of (interface-sd-card-with-sdio-in-stm32) lesson in my project but when i want to use SD-card it make some of received data get lost. and even just open and close a file without writing cussed this problem. could you please help me to solve this problem?

  • Hi, Have you tried to get it work with FreeRTOS?

  • Thank you for a great post. It was a little challenging at first, but I finally got it to work perfectly. I was able to read from disk and write to both Ili9341 and W25Q64.
    I do have one question: How do you read a large file. I have 12 files that I am reading one after the other…no problems there, but when I try to read the 12th file, (size 220K text), The next smaller file (164K text) reads without a problem.
    I’m not a programmer, but have been ‘hacking’ code to get things to work. I believe the problem is that I am running out of memory using malloc() in the FileHandling.c file, but, again, I’m not sure.
    Have you written a library to read a file character by character or by blocks? That would help tremendously in retrieving exceptionally large text files.

    • Sorry, it’s 2a.m. and I just noticed that I didn’t finish a sentence.
      …..but when I try to read the 12th file, (size 220K text), the program hangs. Only a reset will free up the board (STM32F407VET6).

      • I went back an tried each file individually. As it turns out, the 164K file does not read either. The next smaller file is 60K and it reads perfectly. I’m sure it is buffer/memory causing the hangups. Any help you might be able to give would be greatly appreciated.

        • I don’t know buddy. I haven’t tried big files. Maybe you need to use DMA for faster processing.

          • Thanks. I appreciate. I have been tinkling with DMA and other libraries. I can mount a card, or at least the system is saying that the force was successful, but all of my OPENs fail. I came back to your lib because it was quick and easy to read a file.
            I appreciate your response. Keep up the GREAT work. I have learned so much from your tutorials.

  • It does not work. I chagned the FR_DISK_ERROR . I increased the divide factor to 32 as well. [100 Mhz is going to AHB and APB]. Neither the SPI method works nor this. What could be the issue? I use a 16GB sd card of sandisk

  • where can i find file_handling.h and .c?

  • I’m using one board STM32F407VET6 with onboard micro SDCARD reader on it. Do I need to change any pins or user labels in pins in my project? If try to run this code, it returns FR_NOT_READY. The sdcard has 8GB, I formatted it with 1GB using FAT16.

  • Solved, was using sizeof not strlen when sending through uart transmit

  • f_read only recieving 4 bytes of data, running a F411RE any suggestions? I’ve tried everything even using f_gets(). No matter how many big the buffer size is the function freezes after 4 bytes.

  • Hi, thank you for your post.
    Then on my side it doesn’t work.
    I am using STM32F103RCTxx chip for SDIO fat file system.
    FR_DISK_ERR happens when I execute f_mount function.The IDE is STM32 Cube IDE.If you know the reason please help me.
    I am wasting 2 days for this error.
    I will wait for your reply.
    Thank you.

  • And another point. In your Youtube video all data lines have 10K pullup-resistors. Isn’t it possible to just use the built-in pullup of the GPIO? Have you tried if it works aswell? Less components to add in the final build. Cheers mate!

  • Hi great code! Just wondering, is this way faster than writing to SPI? I’m thinking of removing the delay and just log data coming from my ADC. Or won’t it make much of a difference 4 bit sdio vs SPI?

    • I think SDIO is faster compared to SPI. You can try increasing the SDIO clock (by reducing the prescalar) to see if it can go any faster

  • I thank you for the above. Very informative. I am writing a 70 byte CSV time date humidity and temperature data string to an 8Gb card every 5-6 seconds and after exactly 391 data writes it comes up with a HardFault. If I leave the SD card out it works fine. Changing SD cards gives the same fault. Any ideas for me try please? Am using a Nucleo-64 with STM32L476RG

    • GrahamG, did you solve this problem? I’m trying to use the L746RG in 1 bit mode and can’t get past the mount instruction.

  • Thanks for the tutorial, very interesting, methodical and clear.

    I’ve got a question about the stm32F446RE sdio interface and the speed class.Apparently, the stm32F446RE cannot handle microsd card with UHS-1 and class10. It should work like a class10.


  • Roland Manser
    May 25, 2020 9:00 PM

    Thanks for your tutorial.

    Works fine for me. However, I am having trouble in accessing larger cards. Up to 8G fine no problem. Cards with 16 or 32G seem to mount, however no success in writing or reading data. Is there an upper limit for fatfs? I am using STM32L452.

  • Hello controllers tech ,
    Thank you very much for excellent tutorials. I am trying to run above code in STM32F4 Black Board (the one shown in video). i have farmatted my card with both file systems FAT and FAT32 but i am getting these error on serial monitor

    i made a little modification in your code ..
    i have called mount and create file function just before main while loop.
    I have tested other code that is written in standard peripheral driver , that works perfectly fine, please help me ..porting code to HAL library

  • İsmail Erol Coder
    August 15, 2019 12:52 PM

    Hi , controllerstech’s family. I have this kit . I follow your channel. Can u share ili9481 LCD screen using with this kit.
    I didn’t find it.


Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.


Adblocker detected! Please consider reading this notice.

We've detected that you are using AdBlock Plus or some other adblocking software which is preventing the page from fully loading.

We don't have any banner, Flash, animation, obnoxious sound, or popup ad. We do not implement these annoying types of ads!

We need money to operate the site, and almost all of it comes from our online advertising.

Please add to your ad blocking whitelist or disable your adblocking software.