cancel
Showing results for 
Search instead for 
Did you mean: 

How to use the STM32’s backup registers

ST AME Support NF
ST Employee

Introduction

Some of the STM32 microcontrollers have backup registers. These registers can be written/read and protected and have the option of being preserved in VBAT mode when the VDD domain is powered off. In this article we will learn how write, read and protect these registers.
 

1. Prerequisites

  • Hardware:
    • Micro USB cable used to power the Nucleo board from a host machine and to load the code into the STM32.
    • Nucleo-L496

1919.png

  • Software: STM32CubeIDE

 

2. Theory

In this Article we will be using an STM32L496 included on the Nucleo-L496 Nucleo. The STM32L496 includes 32 backup registers (each 32-bit) that can be written/read and protected and are included in the backup domain. This domain also includes the RTC and remains powered by VBAT when VDD power is switched off (provided that VBAT remains powered). After a system reset, the backup and RTC registers are protected against parasitic writes. We will learn how to write, read and protect the backup registers using the STM32Cube HAL drivers.
In this code example, it reads the first backup data register to see if it was written previously and if not, it will unprotect the backup domain and write to it. Once the code is executed the first time, we will do a reset of the STM32 using the button connected to the reset input (NRST). Since the backup domain is preserved by hardware through a reset, the backup register value will remain unchanged.

 

3. Steps 

  1. Open STM32CubeIDE

  2. Create a new project using the NUCLEO-L496ZG board


1920.png

 

  1. Give a name to the project

1922.png
 

  1. Initialize all peripherals with their default settings

1925.png
 

  1. Enable the RTC

The BackUp Registers are part of the RTC peripheral so we will need to enable the RTC to be able to access them. In Pinout & Configuration Tab, go to Timers, and select RTC and then in the RTC Mode and Configuration. Activate the clock source to enable the RTC.
1927.png
 

  1. Generate Code

Project -> Generate Code
1930.png

  1. Add code

We will add the code that checks if the first backup register was already written. If it was previously written with the correct data we read back (0xBEBE) we will turn on LED3 and if not we will un-protect the backup register and write a data to it, protect it and then turn on LED2.
We need to enable the RTC clock as the Backup Registers are part of the RTC. This is done on RTC Configuration Function.
To read a Backup Register use the HAL function call, HAL_RTCEx_BKUPRead.
To be able to write to the Backup register:

  • Enable the PWR Clock (this is already done in the HAL Init function)
  • Enable access to the backup domain
  • Make a HAL function call to write the data: HAL_RTCEx_BKUPWrite
  • Re-Protect the Backup domain

Here is the code to add in main.c in the user code section 2:

  /* USER CODE BEGIN 2 */

  // Check if Data stored in BackUp register1: No Need to write it and then turn LED1
  // Read the Back Up Register 1 Data
    if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) != 0xBEBE)
    {
       // Write Back Up Register 1 Data
       HAL_PWR_EnableBkUpAccess();
       // Writes a data in a RTC Backup data Register 1
       HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0xBEBE);
HAL_PWR_DisableBkUpAccess();
   //Turn LED2
       HAL_GPIO_WritePin(GPIOB, LD2_Pin, GPIO_PIN_SET);

    }
    else
    {
       // data register already written so turn LED3
       HAL_GPIO_WritePin(GPIOB, LD3_Pin, GPIO_PIN_SET);

    }

  /* USER CODE END 2 */
  1. Build the project, enter debug mode and run the code

1933.png


After the project is built, enter a debug session in order to flash the code.
1935.png


We can now terminate the debug session by clicking on the red square icon.
1937.png


This will exit the debug session and then the code will be executed. You should see the blue LED2 that is turned on indicating that the check of the backup register 1 did not pass and that we then wrote a data to it.
Now if you press on the black reset button of the Nulceo, this will re-execute the code but this time the red LED3 will be turned on indicating that the check of the backup register passed because it was previously written.
Now if you unplug and re-plug the Nucleo board, the code will execute again and this time the blue LED2 will be turned on because the backup register was not preserved as the backup domain lost its power (there was no power provided to the VBAT pin). To be able to preserve the backup registers through a power cycle, VBAT must remain powered when VDD is removed, this is called the VBAT mode.


Related links 

Comments
WLiu.3
Associate

Cool​

MNapi
Senior III

I tried to use this code. Each time I turn the power off/on the clock would reset and start counting from begining. I do have battery conectect.

You do not show if and how you can update clock/date/time after power loss.

LauraCx
ST Employee

Hello Mike,

in this example we just show how to use the backup registers and jot the full calendar and time of the RTC.

Niko1007
Associate

Hello,

this tutorial is wrong. Tested on STM32L010F4P6. To use the function HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0xBEBE); no need to call HAL_PWR_EnableBkUpAccess(); or HAL_PWR_DisableBkUpAccess();.

Actually, if the HAL_PWR_DisableBkUpAccess(); function is used, it is not possible to set the RTC wakeup timer with the HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5000, RTC_WAKEUPCLOCK_RTCCLK_DIV16) function after using it. This function ends with a HAL_TIMEOUT error. I could not find the exact cause of the problem, the code gets stuck while waiting for the RTC WUTWF flag to be reset.

If someone understands this and can explain why the functions HAL_PWR_EnableBkUpAccess(); and HAL_PWR_DisableBkUpAccess(); cause HAL_TIMEOUT, or these functions must not be used if the RTC Wakeup timer is used?, or if there is an error in the HAL driver, I will be grateful if you write it here.

Have a nice day.

Details for different STM32 families may differ.

Start a new thread stating hardware you are using and the observed problems.

JW

mrx23
Associate III

Missing one critical point, backup registers can ONLY be written in 32bit mode!

Mariano Iadaresta
Associate II

Hi @Niko1007 

 

I use STM32L052K8T

 

this operation woks for me:

 

void bck_update(){

// Write Back Up Register 1 Data

HAL_PWR_EnableBkUpAccess();

// Writes a data in a RTC Backup data Register 1

wkp_count=wkp_count+1;

HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, wkp_count);

//HAL_PWR_DisableBkUpAccess();

}

void bck_read(){

wkp_count=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1);

}

 

void Sleep()

{

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOA_CLK_DISABLE();

__HAL_RCC_GPIOB_CLK_DISABLE();

__HAL_RCC_GPIOC_CLK_DISABLE();

__HAL_RCC_PWR_CLK_ENABLE(); // Enable Power Control clock

HAL_UART_DeInit(&huart1);

HAL_UART_DeInit(&huart2);

/** Now enter the standby mode **/

/* Clear the WU FLAG */

__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);

/* clear the RTC Wake UP (WU) flag */

__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);

/* Enable WKUP pin */

HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);

if(wkp_count<=30){bck_update();

wkp_time_count=60;}

else{wkp_time_count=600;}

if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, wkp_time_count, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)

{

Error_Handler();

}

sys_ONOFF(0);

HAL_PWR_EnterSTANDBYMode();

}

Version history
Last update:
‎2024-06-11 04:10 AM
Updated by:
Contributors