cancel
Showing results for 
Search instead for 
Did you mean: 

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

ST AME Support NF
ST Employee

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 shows you how to create a file system on a SD card using STM32 and ST Toolsets.
 

1. 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 along with appropriate changes made in the software configuration for a different target board.


1781.png

 

2. Steps

  1. Open STM32CubeIDE
  2. Create a new STM32 project and select the STM32F746G-DISCO template


1782.png

  1. Give a name to your project and then click finish


1783.png
 

  1. Select No for the Board Project Options


1784.png
We will use pre-set peripheral configuration from the board configuration file.
 

  1. Open Associated Perspective, click Yes


1785.png

  1. SDMMC configuration


SDMMC is a peripheral that can be used to interface to a SD card.

  • Enable “SD mode” in “SDMMC1” in “Connectivity” and enable the global interrupt

1786.png

 

  1. FatFs configuration

FatFs is an open-source file system middleware. This is integrated in STM32 Cube Libraries.

  • Configure FatFs as SD Card mode in “MiddleWare”
  • Select PC13 as Detect_SDIO in Platform Settings

1788.png
 

  • Add DMA for TX and RX with default settings


This will permit to achieve best performance.
1789.png

  1. Clock Configuration

 

  • Go to Clock Configuration Tab and Press Yes to resolve the clock issues

1790.png

  1. Project Manager Settings:
  • In the Project Manager Tab, increase the Heap and Stack size because we are using FatFs Middleware that requires more memory:

1791.png

  1. Code generation
  • Now Save the project to generate the code:

1792.png

  1. Open Associated Perspective


1793.png

  1. Add 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 */
  1. Build and flash the code

1794.png
When the code is executed, the SD card will be formatted and a file will be written, you can check the content with an SD card reader.
 

3. Related links

4. Video

Here is a video that explains how to create a File System on SD card using STM32CubeIDE as explained in this article.
STM32 – Creating a File System on a SD card - YouTube


 

Comments
rwils.1
Associate III

Has anyone tried this code on a STM32L471RGT6? It doesn't appear to work and fails at line if(f_mkfs((TCHAR const*)SDPath, FM_ANY, 0, rtext, sizeof(rtext)) != FR_OK

Thanks in advance

DWils.3
Associate

I'm using a different board and connector. My connector's detect switch is active high. I had to change this line of code in fatfs_platform.c from "RESET" to "SET".

if(HAL_GPIO_ReadPin(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) != GPIO_PIN_SET)

This has to be changed to set anytime the ioc file is updated.

Also, try setting the SDMMC clock divide factor to something greater than 0. 0x80 for example. ioc configuration, SDMMC1, Parameters tab.

TKana.1
Associate III

Hi,

I am using the same dev board. Followed all the steps above. My STCubeIDE version is 1.11.2. Program gets stuck at:

if(f_mkfs((TCHAR const*)SDPath, FM_ANY, 0, rtext, sizeof(rtext)) != FR_OK)

{

Error_Handler();

}

with "FR_NOT_READY"

checked and rechecked again, used various SDCards but same.

Any advice is appreciated.

Thanks,

Tim

TKana.1
Associate III

Made it work with couple of modifications:

1- Moved variables to global

move

"

/* 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 */

"

to

"

* USER CODE BEGIN PV */

FRESULT res; /* FatFs function common result code */

uint32_t byteswritten, bytesread; /* File write/read counts */

uint8_t wtext[] = "STM32 FATFS cali666siy great!"; /* File write buffer */

uint8_t rtext[_MAX_SS];/* File read buffer */

/* USER CODE END PV */

"

2- Changed 4B wide operation to 1B operation in "MX_SDMMC1_SD_Init()"

static void MX_SDMMC1_SD_Init(void)

{

 /* USER CODE BEGIN SDMMC1_Init 0 */

 /* USER CODE END SDMMC1_Init 0 */

 /* USER CODE BEGIN SDMMC1_Init 1 */

 /* USER CODE END SDMMC1_Init 1 */

 hsd1.Instance = SDMMC1;

 hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;

 hsd1.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;

 hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;

 hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B; //Start with 1B instead 4B. Later "SD_Widebus_Enable" command makes it 4B

 hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;

 hsd1.Init.ClockDiv = 0;

 /* USER CODE BEGIN SDMMC1_Init 2 */

 /* USER CODE END SDMMC1_Init 2 */

}

now it works OK. Tested with 4GB and 16GB FAT32 formatted uSD cards

Tim

RRibe
Associate II

Thank's for your advice, now my SD Card program works fine.

Kunaalkk1
Associate II

My code does not work, I even moved some variables to global, still not working. Please help me out. My hardware PCB uses a 4-bit wide bus, and my SD Card is FAT32 8GB. It only works upto f_mount() which returns FR_OK, but after that, the f_open returns FR_DISK_ERR.

Stanys.1
Associate

I had the same problem with f_mount(). I use the same solution as described by JBond.1

https://community.st.com/t5/stm32cubemx-mcus/sdcard-does-not-work-with-4bits-wide-bus/td-p/602607

It works fine! You don't need to do the steps described by TKana.1

I use STM32CubeIDE Version: 1.13.2 and STM32CubeF4 Firmware Package V1.27.0 / 11-February-2022

Chaitanya96
Associate II

Hello, Can anyone Tell me is it mandatory to Format a new SD Card before writing or Reading data in STM32 MCU. Currently I am facing an issue wherein whenever I try to write data into a new non-formatted SD Card, It gives me an error but whenever I try to write data into a SD card using a card reader, it gets written. Thanks for help in advance.

AScha.3
Chief III

Hi,

>is it mandatory to Format a new SD Card

NO!  You should never format a new sd-card, because they are format to the optimum for that card.

So format -especially as first action on a new system- might with good chance destroy the card or at least make it worse (getting slower) . Especially on new, big (> 32GB) cards in exfat format.

Also dont write - until mount, open directory and reading files working perfect.  Then can try write something.

johngj
Senior

Like others it failed at f_mkfs.  I watched the video for this guide...

https://www.youtube.com/watch?v=I9KDN1o6924 

...and there is a step missing from this written guide.  The missing step, as shown in the video, is to add the DMA Rx and Tx..

johngj_0-1706021484303.png

Since adding the dma rx/tx and changing the SD mode from 4 bit wide to 1 bit, it now works.

For some reason it does not work in SD mode 4 bit wide

MNapi
Senior III

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 III

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
Chief III

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

Alexey Maslov
Associate

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

 

brunob45
Associate

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 

Version history
Last update:
‎2024-06-04 04:57 AM
Updated by: