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


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

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

  Mount_SD("/");
  Format_SD();
  Create_File("FILE1.TXT");
  Create_File("FILE2.TXT");
  Unmount_SD("/");

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.


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

indx++;

HAL_Delay(2000);

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



Result

file data
uart output

Check out the Video Below




Info

You can help with the development by DONATING Below.
To download the project, click the DOWNLOAD button.

Subscribe
Notify of

34 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Vadhya
1 year ago

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
1 year ago

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?

Raj
1 year ago

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

Travis
1 year ago

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

mahdie
2 years ago

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?
thanks

Kamil
3 years ago

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

GregoryT
3 years ago

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.

GregoryT
Reply to  GregoryT
3 years ago

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

GregoryT
Reply to  GregoryT
3 years ago

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.

GregoryT
Reply to  admin
3 years ago

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.

raja
3 years ago

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

cordy
3 years ago

where can i find file_handling.h and .c?

Gomnam
Reply to  cordy
3 years ago

Download the whole project and the files are in the “src” and “inc” folder

raj
Reply to  Gomnam
2 years ago

but the files are different in video and in the folders

Guilherme
3 years ago

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.

Alex
Reply to  Guilherme
2 years ago

i have the same board and exactly the same problem. did you manage to get it to work?

Marko
4 years ago

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

Marko
4 years ago

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.

song il
4 years ago

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.

JohnM
4 years ago

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!

JohnM
4 years ago

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?

GrahamG
4 years ago

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

ClarkS
Reply to  GrahamG
3 years ago

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.

papageno
4 years ago

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.

Regards,

Roland Manser
4 years ago

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.

ansh
4 years ago

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
5 years ago

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.