Skip to main content
ST AME Support NF
ST Employee
September 24, 2021

How to create a file system on an SD card using STM32CubeIDE

  • September 24, 2021
  • 16 replies
  • 79824 views

Introduction

Data logging applications require storing large amounts of data over a period of time. SD cards are a convenient solution for storing data and many STM32 products include the proper hardware interface. Using a standard file system to write data on an SD card ensures that the data is easily accessible on another device or computer. Adding a file system along with an SD card driver is easy to do using the various ST tools available for the STM32 family of microcontrollers.

This article details the process of configuring the SDMMC peripheral for accessing an SD card and configuring the FatFs middleware to create a file system using STM32 and ST toolsets.

Note that this article is also available in video form: STM32 – Creating a file system on an SD card - YouTube
 

Prerequisites

STM32 Discovery kits as well as evaluation boards include an SD card socket. While this example uses the STM32F746G-DISCO board, any other STM32 board with an SD card socket can be used. Ensure appropriate changes are made in the software configuration to accommodate a different target board.


1781.png

 

1. Implementation steps

1.1 Create and open STM32CubeIDE project

Firstly, we need to create a STM32CubeIDE project where we configure the application to interface with the SD card.

  1. Open STM32CubeIDE, and create a new STM32 project, selecting the STM32F746G-DISCO template.pepfof_2-1755096131183.png
  2. Give a name to your project and then click finish.1783.png
  3. Select [No] for the Board Project Options.1784.png
  4. Select [Yes] when asked to Open Associated Perspective.1785.png

After this is done, the device configuration tool view is open in STM32CubeIDE. From here on, we can configure the MCU to be able to utilize the board's SD card slot.

2. SDMMC configuration

STM32 MCUs use the SDMMC peripheral to interface to an SD card, we need to configure it before we can write code that uses it. In this article, we also configure DMA access to the SDMMC peripheral to maximize performance.

  1. In the Device Configuration Tool view, for the “SDMMC1” peripheral, which is located in the “Connectivity” category, set the "Mode" parameter to "SD 4 bits Wide bus".1786.png
  2. In the DMA Settings panel, add DMA requests for SDMMC1_TX and SDMMC1_RX with their default settings.pepfof_0-1755095525756.png
     
     
     
     

    After adding these requests, the DMA settings panel should look like this:

    pepfof_1-1755095631544.png

3. FatFs configuration

FatFs is an open-source file system middleware integrated in STM32Cube libraries. It is able to directly utilize the SDMMC peripheral to act as a disk device for the FAT file system. This is also configured through the Device Configuration Tool view.

  1. In the "Middleware" category, for the FATFS middleware, enable the "SD card" option. In the "Platform Settings" panel, select "PC13 [uSD_Detect]" as a solution for "Detect_SDIO".1788.png
  2. As we are using DMA to access the SDMMC peripheral, in the "Advanced Settings" panel, enable the "Use dma template" option.pepfof_3-1755096797869.png

     

4. Project Configuration and code generation

After the peripheral and middleware configuration is complete, we will also need to modify the clock configuration and certain project settings.

  1. The default clock configuration for this MCU presents an issue with the clock input to the SDMMC controller. This needs to be resolved, and can be done easily by going to the "Clock Configuration" tab and selecting [Yes] when asked to automatically resolve clock issues.1790.png
  2. Lastly, the FatFs middleware requires additional memory for the Heap and the Stack. In the Project Manager tab, set the "Minimum Heap Size" and "Minimum Stack Size" parameters for the Linker Settings to "0x400" and "0x800" respectively.1791.png
  3. When you save the project, the IDE presents you with an option to generate code according to your Device Configuration Tool setup. Select [Yes] when asked to generate the code.1792.png
  4. Select [Yes] when asked to Open Associated Perspective. This will take you to your project's generated main source file.1793.png

5. Create a demo application

Now that SDMMC and FatFs configuration is complete and the appropriate code is generated, we can start writing user code that accesses the SD card. For the purposes of this article, the code sample below mounts the SD card, create a new FAT file system on it, create a file named "STM32.TXT", and write "STM32 FATFS works great!" to it.

You may copy this snippet into your main.c file - take note of the "/* USER CODE BEGIN x */" markers and place the two sections in the places that these are located in your code.

/* USER CODE BEGIN 1 */
FRESULT res; /* FatFs function common result code */
uint32_t byteswritten, bytesread; /* File write/read counts */
uint8_t wtext[] = "STM32 FATFS works great!"; /* File write buffer */
uint8_t rtext[_MAX_SS];/* File read buffer */
/* USER CODE END 1 */
 ...
/* USER CODE BEGIN 2 */
	if(f_mount(&SDFatFS, (TCHAR const*)SDPath, 0) != FR_OK)
	{
		Error_Handler();
	}
	else
	{
		if(f_mkfs((TCHAR const*)SDPath, FM_ANY, 0, rtext, sizeof(rtext)) != FR_OK)
	 {
			Error_Handler();
	 }
		else
		{
			//Open file for writing (Create)
			if(f_open(&SDFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
			{
				Error_Handler();
			}
			else
			{

				//Write to the text file
				res = f_write(&SDFile, wtext, strlen((char *)wtext), (void *)&byteswritten);
				if((byteswritten == 0) || (res != FR_OK))
				{
					Error_Handler();
				}
				else
				{

					f_close(&SDFile);
				}
			}
		}
	}
	f_mount(&SDFatFS, (TCHAR const*)NULL, 0);
/* USER CODE END 2 */

6. Build and flash the code

Finally, you may build the project and run it on the device by starting a debug session.

1794.png
pepfof_0-1755098006776.pngWhen the code is executed, the SD card is formatted and the text file is written to it. Inserting the SD card into a host PC, you may read the file, as presented in the screenshot to the right.

 


 

Related links

 

 

Video

 

This topic has been closed for replies.

16 replies

MNapi
Senior II
January 31, 2024

I had the same problems. I couldn't not to get it working in 4bit mode but I got it working in 1 bit mode.

Actually when I tried older version of CubeMX the 4bit mode works. I think there is bug in latest CubeMX.

 

I got this reply from STM32 tech support

On December 4, 2023 at 2:34 PM

It turned out to be a problem on CubeMX code generation that we cannot configure SDMMC and the FatFS at the same time. This will be fixed in the next release of CubeMX.

 

I tried new chip and the same problem. I set up 1bit mode in CubeMX, I moved to:

/* USER CODE BEGIN 0 */
FRESULT res; /* FatFs function common result code */
uint32_t byteswritten, bytesread; /* File write/read counts */
uint8_t wtext[] = "new file test"; /* File write buffer */
uint8_t rtext[_MAX_SS];/* File read buffer */
/* USER CODE END 0 */

If you do not have PIN detect for SD card connected change this line change it in fatfs_platform.c

 

MNapi
Senior II
February 1, 2024

Here is a small update. I tired to setup in SD 4 bits in CubeMX and of course it did not work. New customs another board with STM32H7A3ZIT6.  I generated the code anyway and made some custom changes. I initialize it first in 1 bit mode. Then in 4 bit and it worked. DMA setting did not have any influence if it works or nor. My SD card works with speed up to 64 MHz, setup the clock in CubeMX. Also make sure the settings in

 

static void MX_SDMMC2_SD_Init(void)
{

/* USER CODE BEGIN SDMMC2_Init 0 */
hsd2.Instance = SDMMC2;
hsd2.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
hsd2.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
hsd2.Init.BusWide = SDMMC_BUS_WIDE_1B;

/* USER CODE END SDMMC2_Init 0 */

/* USER CODE BEGIN SDMMC2_Init 1 */

/* USER CODE END SDMMC2_Init 1 */
hsd2.Instance = SDMMC2;
hsd2.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
hsd2.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
hsd2.Init.BusWide = SDMMC_BUS_WIDE_4B;
hsd2.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
hsd2.Init.ClockDiv = 0;
/* USER CODE BEGIN SDMMC2_Init 2 */

/* USER CODE END SDMMC2_Init 2 */

}

 

here are also fatfs settings which work for mefat.png

 

AScha.3
Super User
February 1, 2024

I have on H743VI  SD-card running with no problems (in 4 bit mode, 50MHz clock) :

 /* USER CODE END SDMMC1_Init 1 */
 hsd1.Instance = SDMMC1;
 hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
 hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_ENABLE;
 hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
 hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
 hsd1.Init.ClockDiv = 1;
 /* USER CODE BEGIN SDMMC1_Init 2 */
 if (HAL_SD_Init(&hsd1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE END SDMMC1_Init 2 */

 STM32Cube FW_H7 V1.10.0

If you feel a post has answered your question, please click on " Best Answer ".
Visitor II
February 7, 2024

Had similar issue on STM32F746G-Disco EVB. Changing SDMMC_BUS_WIDE_4B to SDMMC_BUS_WIDE_1B resolved the issue

STM32CubeIDE  Version: 1.13.2  Build: 18220_20230914_1601

 

Graduate
February 27, 2024

Same here with STM32F446.

I fixed the SDIO bug by adding the following line:

static void MX_SDIO_SD_Init(void)
{
...
/* USER CODE BEGIN SDIO_Init 2 */
hsd.Init.BusWide = SDIO_BUS_WIDE_1B; //add this line, so that the automatic code generetation with STM32CubeIDE does not override the configuration
/* USER CODE END SDIO_Init 2 */
}

 As proposed here SDCARD does not work (FR_NOT_READY) when migrating from FW_F4 V1.27.0 to newer FW_F4 V1.27.1 

HDaji.1
Senior
June 23, 2025

I am using Nucleo-F446ZE board.

The Platform Settings at FATFS stage, the ioc editor cannot find solutions for Detect_SDIO option.

ioc_warning.pngCan anyone give some advice on how to resolve it?