0% found this document useful (0 votes)
12 views7 pages

STM32 Flash Memory - Storing Data in Non-Volatile Memory

This document provides a tutorial on using STM32 Flash Memory to store data permanently, addressing the issue of data loss during power outages. It explains the structure of flash memory, the process of writing and reading data, and includes code examples for implementing these functions using STM32 HAL API. The tutorial also offers insights into testing the library with a counter that retains its value after a power cycle.

Uploaded by

Papai Mk
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views7 pages

STM32 Flash Memory - Storing Data in Non-Volatile Memory

This document provides a tutorial on using STM32 Flash Memory to store data permanently, addressing the issue of data loss during power outages. It explains the structure of flash memory, the process of writing and reading data, and includes code examples for implementing these functions using STM32 HAL API. The tutorial also offers insights into testing the library with a counter that retains its value after a power cycle.

Uploaded by

Papai Mk
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Home Courses Blog Free download My Library Contact Private sessions

Log In

STM32 Flash memory to store data permanently


Oct 13, 2025

Imagine, you are recording a sensor and storing it using some variables in your code. At some point, BOOM, the microcontroller is disconnected from a power supply and
you lose the recorded data. Once you power on the MCU, the variables hold default values, not sensor readings. Is there any remedy to this problem, so you can store data
permanently within the MCU to retrieve it after the power outage? The answer to this question lies in using STM32 Flash Memory which allows us to keep the data after
power outage. So, this tutorial is about explaining general concepts of flash memory, writing to flash memory, and reading data from flash memory. I will use the Nucleo-
l4768rg board, but you can use any other type of STM32 microcontroller. Also, I will use STM32 HAL API develop the code.

First, let's look at the table below which shows the structure of flash memory. You can find it within a reference manual of the STM32 MCU you are using. If you do not
know how to work with the reference manuals, please refer to my STM32 Intro Course: STM32 Intro Course

As you see, the memory unit might contain several banks and it is divided into pages. In my case, I have 512 pages and each page can contain 2048 Bytes. These numbers
might vary from one microcontroller to another. The primary purpose of flash memory is to keep the execution instructions. When you write code and compile it, your
code will be translated into a set of instructions that your microcontroller can understand. When you press 'run', these instructions will be sent to the microcontroller and
stored inside of flash memory. The microcontroller stores the instructions from the top starting from the 0x8000000 memory address. Therefore, it is super critical not
to use flash memory from the top. Instead, we have to use the last pages, which are not allocated by the instructions. Another important thing is we have to erase
the memory space before storing data. Otherwise, it is not going to work.
STM32 Flash Memory Library, Header File
To work with flash memory, I created source and header files. The code below belongs to the header file 'flash_store_data.h' and it has two function prototypes.
#ifndef INC_FLASH_STORE_DATA_H_
#define INC_FLASH_STORE_DATA_H_

#include "stdio.h"
#include "main.h"

void store_flash_memory(uint32_t memory_address, uint8_t *data, uint16_t data_length);


void read_flash_memory(uint32_t memory_address, uint8_t *data, uint16_t data_length);

#endif /* INC_FLASH_STORE_DATA_H_ */

STM32 Flash Memory Library, Source File


The source file contains the implementation of the functions. First, let me show a function to store data within flash memory.

Initially, as I said, we have to erase memory before writing. For that purpose we have FLASH_EraseInitTypeDef. We need to define all the members of the struct before
erasing the memory:

TypeErase: equals FLASH_TYPEERASE_PAGES, meaning that we will erase specific pages, not the whole flash memory
Page: Onset page.
NbPages: number of pages we want to erase
Flash Bank

Once we define them, we can erase the memory by calling HAL_FLASHEx_Erase function. After erasing, we can start sending data to the flash memory. To do that, we
will use HAL_FLASH_Program function. The first argument is the size of a data chunk that we can convey per iteration. It can be either Single Word (4 bytes) or Double
Word (8 bytes). In my microcontroller, this argument has to be FLASH_TYPEPROGRAM_DOUBLEWORD. It means that I can send a data piece with uint64_t data
type that can contain 8 bytes of data. Using a while loop, I iterate through data, sending it to the flash memory. Then I have to Lock the flash memory by calling
HAL_FLASH_Lock function.
#include "flash_store_data.h"
#include "stdint.h"
#include "stm32l4xx_it.h"

typedef uint64_t flash_datatype;


#define DATA_SIZE sizeof(flash_datatype)

void store_flash_memory(uint32_t memory_address, uint8_t *data, uint16_t data_length)


{
uint8_t double_word_data[DATA_SIZE];
FLASH_EraseInitTypeDef flash_erase_struct = {0};
HAL_FLASH_Unlock();
// defining the members of a struct
flash_erase_struct.TypeErase = FLASH_TYPEERASE_PAGES;
// defining an onset number page to be erased
flash_erase_struct.Page = (memory_address - FLASH_BASE) / FLASH_PAGE_SIZE;
// number of pages to remove
flash_erase_struct.NbPages = 1 + data_length / FLASH_PAGE_SIZE;
// identify the flash bank
if(memory_address > FLASH_BANK1_END && memory_address < FLASH_BANK2_END )
{
flash_erase_struct.Banks = FLASH_BANK_2;
}
else if(memory_address > FLASH_BASE && memory_address < FLASH_BANK1_END)
{
flash_erase_struct.Banks = FLASH_BANK_1;
}
else
{
printf("illegal memory address \n");
UsageFault_Handler();
}
uint32_t error_status = 0;

// erase the pages, this step is mandatory


HAL_FLASHEx_Erase(&flash_erase_struct, &error_status);
int i = 0;
// using while loop, convey all data to the flash memory
while ( i <= data_length)
{
double_word_data[i % DATA_SIZE] = data[i];
i++;
if (i % DATA_SIZE == 0)
{
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, memory_address + i -
DATA_SIZE, *((uint64_t *)double_word_data));

}
}
// convey data if something left
if (i % DATA_SIZE != 0)
{
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, memory_address + i
- i % DATA_SIZE, *((flash_datatype *)double_word_data));
}
// lock the memory
HAL_FLASH_Lock();
}

It is worth mentioning that if your MCU supports FLASH_TYPEPROGRAM_SINGLEWORD instead Double Word, define flash_datatype as uint32_t:
typedef uint32_t flash_datatype;

Finally, we have a function to get data from the flash memory. Using for loop, I read all the necessary bytes from the memory unit:

void read_flash_memory(uint32_t memory_address, uint8_t *data, uint16_t data_length)


{
for(int i = 0; i < data_length; i++)
{
*(data + i) = (*(uint8_t *)(memory_address + i));
}
}

To test the library, we can use the code below. In this code, a counter is incremented every second within a while loop and stored within the flash memory. If you power
off the microcontroller and start the code again, the program will restore the counter value from the Flash memory. TO store data, I used the last page of flash memory
which has an address of 0x080FF800

To display the counter value, I use printf function based on SWV. You can get more information about SWV by referring to this article: printf using SWV. Or, you can use
live expressions on debug mode.

#include "main.h"
#include "flash_store_data.h"

#define FLASH_ADDRESS_COUNTER 0x080FF800


uint32_t counter;
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM4_Init();
read_flash_memory(FLASH_ADDRESS_COUNTER, (uint8_t *)&counter, sizeof(counter));
if(counter == 0xffffffff)
{
counter = 0;
}
else
{
printf("counter value is %d \n", (int)counter);
}
while (1)
{
counter++;
HAL_Delay(1000);
printf("counter is incremented: %d \n", (int)counter);
store_flash_memory(FLASH_ADDRESS_COUNTER, (uint8_t *)&counter, sizeof(counter));
}
}

The source code is available on GitHub. You can get access by joining the Steppeschool community:

Patreon Steppeschool COmmunity

Video version of the tutorial:

Use STM32 Flash Memory to store data Permanently


Build Your Own Quadcopter Flight Controller

Robotics course in designing a Drone Flight Controller from scratch using STM32

Check it out
Balancing Robot: Design, Control, and Programming

Build Self-balancing robot from scratch, mastering STM32 MCU programming and robotics topics.

Check it out
STM32 Attitude Estimation: IMU, Euler Angles, Filters

Master attitude estimation: IMU sensor interfacing, Euler angles, Quaternions, and Kalman Filter. Learn practical STM32 programming for SPI, UART, and Timer
interrupts.

Check it out
STM32 Programming course for beginners

Project-based STM32 Programming course to learn STM32 hardware peripherals, CubeMx, HAL API, Communication interfaces, and bare metal programming.

Check it out

© 2025 BUSINESS NAME. ALL RIGHTS RESERVED.



Powered by Kajabi

Join The FREE Challenge


Enter your details below to join the challenge.

You might also like