STM32 SD Card SPI & FatFS [Tutorial + Examples]

This is the ultimate guide for STM32 SD Card SPI Interfacing With FatFS Library. You’ll learn how to use SD Cards with STM32 microcontrollers using the SPI interface module. We’ll create some STM32 SD Card Example Test Projects to verify what we’ll be learning in this tutorial.

Table of Contents

  1. STM32 SD Card Interfacing
  2. STM32 SD Card SPI Interfacing
  3. STM32 SD Card FatFS SPI Driver
  4. STM32 SD Card SPI & FatFS Example Project
  5. STM32 SD Card SPI Troubleshooting
  6. Wrap Up

STM32 SD Card Interfacing

Some STM32 microcontroller series have an integrated SDIO (SDMMC) hardware peripheral that’s designed specifically to interface SD cards at the maximum speed.

However, SD cards can still be used over SPI communication which is available in all STM32 microcontrollers and pretty much every single microcontroller in the market. And we’re going to focus on STM32 SD Card SPI interfacing in this tutorial.

STM32 SPI Vs SDIO Vs SDMMC

SPI is a generic serial peripheral interface and can still be used to interface SD cards with low-end microcontrollers at a relatively lower speed of communication and a much simpler software stack. That’s why SPI is the most commonly used interface for SD cards in a lot of projects.

SDIO is a hardware peripheral designed specifically for interfacing (SD Cards, SDIO Cards, and MultiMedia Cards “MMC”) with the APB2 peripheral bus in “some” of the STM32 microcontrollers. Given that it’s dedicated to SD card interfacing, it’s going to be a much faster way of communicating with SD cards (4x the speed you can get with an SPI interface).

SDMMC is a hardware peripheral designed specifically for interfacing (SD memory cards, SDIO cards, and eMMC devices) with the APB2 peripheral bus in “some” of the STM32 microcontrollers. It’s almost identical to the SDIO interface but it supports eMMC devices additionally and can go up to way higher transfer speeds (in 8-Bit mode).

❕ Note

I was able to successfully run this tutorial’s example project @ 18MBits/s SPI speed. However, it’s advisable to start testing your card @ a lower speed of communication (like 2.25MBits/s or 4.5MBits/s) and gradually increase the speed until reaching the limit of your hardware setup.


STM32 SD Card SPI Interfacing

In this section, we’ll discuss how to interface STM32 microcontrollers with SD Cards using the SPI bus.

Micro SD Card Memory

Preparing The SD Card

Use an SD Card Reader for this step.

Before using your SD card, make sure you’ve Formatted it to the FAT (FAT32/FAT) file system (in your operating system of choice).

❕ Note

Some SD Cards just don’t work with the hardware/firmware setup we’re going to use in this tutorial. I’ve tested a handful of SD cards before reaching this conclusion. The card size is not the only reason for communication failure. In fact, a 16GB card worked well for me while a 2GB card did not. But another 1GB did work properly. Therefore, it’s not 100% about the card size, some SD cards just don’t support SPI.

Hint: smaller-sized SD Cards (<8GB) are more likely to support the SPI interface.

STM32 SD Card Hardware Design

If you’re designing your own STM32-based PCB board project that requires having an SD card memory slot onboard, you’d need to consider a 3.3v voltage regulator IC to provide the necessary power to the SD card. A level shifter IC (like 74LVC125A) is typically used in SD card modules to make sure that the SPI bus lines are all in the 3.3v logic level.

STM32 SD Card Module

For quick prototyping and project idea testing, we commonly use the SD card module shown below which provides a very easy way to interface SD cards with various microcontrollers. And that’s what we’re going to use in this tutorial’s example project.

SD Card Module Pinout Diagram

SD-Card-Module-Pinout-Diagram

Buy an SD Card Module (on Amazon)

STM32 SD Card Module SPI Wiring Diagram

This is the wiring diagram for the STM32 blue pill development board with an SD card module using the SPI interface. The USB-TTL Converter is used to send messages to the PC for testing the SD card read/write operations.

STM32-SD-Card-SPI-Wiring-Connection-Diagram

❕ Note

The SD card interface requires a bit more current than that can be provided from the USB debugger which will lead to failure in mounting the SD card and all other operations as well. The solution for this issue is to use a decent power source like a power bank to the USB port of the blue pill board, for example.


STM32 SD Card FatFS SPI Driver

Let’s now move on to the FATFS_SD driver that we’ll be using alongside the STM32 auto-generated FatFS library code from the CubeMX tool. This driver has a lot of functions implementations for (SPI interface wrappers, SD card operations, and user_diskio functions). The original driver is not mine, its credit goes to eziya and you can read more about it here.

In the next section, we’ll discuss how to integrate this STM32 FATFS_SD driver into our STM32 CubeIDE project step-by-step.

STM32 FATFS_SD Directory & Files

The STM32 FATFS_SD library is part of the MIDWARE (middleware software layer). The driver consists of 2 core files: (a header file & a source file).

  • FATFS_SD.h
  • FATFS_SD.c
STM32-FATFS_SD-Driver-SD-Card-SPI-Tutorial

You can download this driver using the link below as you’ll need to have this folder while implementing the example project in the next section.

Download The MIDWARE/ FATFS_SD Driver Folder


STM32 SD Card SPI & FatFS Example Project

In this example project, our ultimate goal is to test the functionalities provided by the fatfs library and use it to create a text file, write to it, read the file, modify the existing file, and delete the file. We’ll monitor the progress of this test sequence using serial UART messages printed to the serial monitor on the PC.

SD Card Tests Included in This Project:

  • Mount The SD Card
  • Find and print the card size & free space
  • Create a new Text File
  • Write to the text file using the f_puts() function
  • Write to the text file using the f_write() function
  • Read from the text file using the f_gets() function
  • Read from the text file using the f_read() function
  • Modify (update) an existing file
  • Delete the file
  • Unmount the SD Card

Please, follow The step-by-step guide below to create the project, configure the needed hardware peripherals in CubeMX, add the FATFS_SD driver folder, and run the test project on your STM32 dev board.

Step #1

Create a New Project in STM32CubeMX

The first step is to head over to STM32CubeMX, create a new project, enable the SWD (serial wire debug), enable the external HSE oscillator, and configure the RCC clock to 72MHz (for the blue pill).

Step #2

Configure 1x UART Port

Enable any UART module to be used as a serial communication with the PC using a USB-TTL converter. For me, I’ve enabled the UART1 module with default configurations.

STM32-UART1-CubeMX-Default-Configurations

Step #3

Configure The SPI Module To Be Used For SD Card Interfacing

Here, I’m using the SPI2 module but you can use any other SPI module available in your STM32 target microcontroller. Set the speed prescaler for at least 8 while testing this project for the first time. Gradually Increase the speed if you need later on if everything is working okay.

STM32-SPI2-CubeMX-Default-Configurations

Add a GPIO Output Pin For The CS control line

In this project, I’m using the pin PB12 for the CS signal.

Step #4

Enable The FatFS Library

Edit the library configurations as shown below.

STM32-FatFS-CubeMX-Configurations

Once you’re done with CubeMX configurations, generate the project code and head over to STM32CubeIDE.

Step #5

Copy & Paste The FATFS_SD Library Folder

Copy the provided library folder (MIDWARE/FATFS_SD) and open the STM32CubeIDE. In STM32CubeIDE, right-click the project name and paste the library folder.

STM32 FatFS_SD Driver CopySTM32 FATFS_SD Driver PastingSo it’ll look like this at the end:
STM32 SD Card SPI FatFS Project Files

Step #6

Add The Library Directory To Paths & Symbols

The FATFS_SD library folder has been added to our project but it’s not yet considered as a source code directory, so it won’t be compiled and give you a linking error in the linking stage if you call any of its functions.

Right-click the project name and click Properties. And navigate to C/C++ paths and symbols, and source locations tab. In the source locations tab, click Add folder and add our library folder (MIDWARE).

Step #7

Configure The FATFS_SD Library Using The Header File

Open the FATFS_SD.h file and modify the configuration parameters to match your hardware settings.

Here are the default settings at the beginning of the FATFS_SD.h file.

You can change the SPI2 module’s number if you’re using another SPI module. And the same goes for the CS GPIO/Pin.

Step #8

Edit The (stm32f1xx_it.c) File

The FATFS_SD driver requires some delays and timing management. The way it handles this task is by using the built-in SysTick Timer interrupt as well as a couple of counter variables.

Open the stm32f1xx_it.c file, or the equivalent file if you’re using another STM32 microcontroller series target. Paste in the following two global variables near the beginning of the file.

Scroll down the file till you find the SysTick_Handler() function. Paste the following lines of code, so the function will finally look like the one shown below.

And that’s all about it. Let’s move to the next step.

Step #9

Edit The (user_diskio.c) File

Add the following #include line at the beginning of the file.

Edit the empty functions you’ll find in this file by adding the appropriate function call inside its implementation, and make it look like the shown below.

That’s all about this file. Now, let’s move to the last step!

Step #10

Copy The Project’s Code Below into Your Main.c File

Build The Project, Flash The Code To The STM32 Board, and Start Testing!

STM32 SD Card SPI & FatFS Example Code

The Application Code For This Example (main.c)

Test Setup

This is my test setup for this example project. I’m using a 16GB SD card as well as a USB-TTL converter to send test result messages to the PC. The SD card module and USB-TTL converter are wired to the STM32 blue pill board according to the wiring diagram shown earlier near the beginning of this tutorial.

STM32-SD-Card-SPI-Example-FatFS-Project

Testing Result

Here is the test result that’s printed on the serial monitor.

STM32-SD-Card-SPI-Example-Test-Result

And this is the content of the SD card after running this example project as shown on my PC file manager.

STM32-SD-Card-SPI-Example-Text-File-Write-Test-Result


STM32 SD Card SPI Troubleshooting

1. Use an External Power Source like a power bank or a battery because this project needs a bit more current than what can be delivered using the debugger’s USB and this may be the reason why your SD Card is failing to mount successfully.

2. Start With a Low SPI Speed like 2.25MB for example and see if it works well, you can then increase the speed gradually until it reaches the fundamental limitation of your hardware setup. The High starting speed of SPI can be the reason why the STM32 microcontroller is failing to properly communicate with the SD card.

3. Try Different SD Cards Before Attempting Major Code Changes because some SD cards just do not support communication over SPI at all. And maybe this is the reason why your SD Card is failing to mount successfully and it will never, TBH. Therefore, you need to try a different card before attempting to change your code in the hope that it’ll fix the issue.

4. Make Sure You Didn’t Forget Anything About Steps: (#8 & #9) while following along the implementation steps of the provided example project. The easiest way to know that your problem is related to the user_diskio.c file is by probing the CS pin or any SPI line. If you see nothing, then you’ve missed step #9 of the implementation guide.


Required Parts For STM32 Examples

All the example Code/LABs/Projects in this STM32 Series of Tutorials are done using the Dev boards & Electronic Parts Below:

QTY.Component NameAmazon.comAliExpresseBay
1SD Card ModuleAmazonAliExpresseBay
1SD Card Reader (For PC)AmazonAliExpresseBay
1SD Card 8GBAmazonAliExpresseBay
1STM32-F103 BluePill Board (ARM Cortex-M3 @ 72MHz)AmazonAliExpresseBay
1Nucleo-L432KC (ARM Cortex-M4 @ 80MHz)AmazonAliExpresseBay
1ST-Link V2 DebuggerAmazonAliExpresseBay
2BreadBoardAmazonAliExpresseBay
1LEDs KitAmazonAmazonAliExpresseBay
1Resistors KitAmazonAmazonAliExpresseBay
1Capacitors KitAmazonAmazonAliExpress & AliExpresseBay & eBay
1Jumper Wires PackAmazonAmazonAliExpress & AliExpresseBay & eBay
1Push ButtonsAmazonAmazonAliExpresseBay
1PotentiometersAmazonAliExpresseBay
1Micro USB CableAmazonAliExpresseBay

★ Check The Links Below For The Full Course Kit List & LAB Test Equipment Required For Debugging ★

Download Attachments

You can download all attachment files for this Article/Tutorial (project files, schematics, code, etc..) using the link below. Please consider supporting our work through the various support options listed in the link down below. Every small donation helps to keep this website up and running and ultimately supports the whole community.


Wrap Up

In conclusion, we’ve discussed how to interface STM32 microcontrollers with SD Card memory over the SPI bus using the FatFS library as well as the FATFS_SD. The provided example project should be a very good starting point for your next STM32 SPI SD Card interfacing project. Make sure to carefully follow the implementation guide step-by-step to get it to work as expected.

You can also explore the other parts of the STM32 SD Card tutorials series for more information about the other STM32 SD Card interfacing options.

This Tutorial is Part of The Following Multi-Part Tutorial Series:

Share This Page With Your Network!
Join Our +25,000 Newsletter Subscribers!

Stay Updated With All New Content Releases. You Also Get Occasional FREE Coupon Codes For Courses & Other Stuff!

Photo of author
Author
Khaled Magdy
Embedded systems engineer with several years of experience in embedded software and hardware design. I work as an embedded SW engineer in the Automotive & e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI/ML, and other fields I'm passionate about.
I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?

Leave a Comment