STM32F4 RTC with CubeMX tutorial

by Matthew Watson


Posted on October 12, 2018 at 19:14 PM


This guide will illustrate setup of the RTC on the NUCLEO-F446RE using CubeMX. It aims to fill the gap between the manuals on the HAL drivers, the STM32F4 referece manual and the CubeMX cnfiguration boxes.

Summary

The document will follow the steps for configuring the NUCLEO-F446RE and setting up the project to use the RTC with the LSE.

The steps are:

  • configure the RCC, to have the LSE to be the onboard crystal oscillator
  • configure the RTC
  • set the LSE to be the clock for the RTC
  • write some code to set the clock and read the clock

The hardware

The Nucleo

  • STM32re chip This project will use a Nucleo baord, with the STM32F446re chip
  • LSE The nucleo has an LSE fitted for use with the RTC (refer image below)
  • VBATThe Nucleo dosn't have a battery for backup of the time so to save current time one is needed. On the Nucleo this involves removing a solder bridge and adding a coil cell battery (maximum volatge of 1.65 to 3.6V).

STM32F4 MCU

The STM32F4 has a real-time clock (RTC).. .an independent BCD timer/counter. The RTC provides a time-of-day clock/calendar, two programmable alarm interrupts, and a periodic programmable wakeup flag with interrupt capability. The RTC also includes an automatic wakeup unit to manage low power modes. Two 32-bit registers contain the seconds, minutes, hours (12- or 24-hour format), day (day of week), date (day of month), month, and year, expressed in binary coded decimal format (BCD). The sub-seconds value is also available in binary format. From stmf4 manual.

LSE

No hardware change to use the LSE is requried, only software configuration detialed in the CubeMX steps below.

Exert from user manual

VBAT

Battery backup needed to save current time -- otherwise the RTC counter will be reset on power loss -- for the Nucleo this involves:

  1. Remove solder bridge - else backup battery will power the device
  2. Connect coin cell to the Nucleo pin (battery volatge range 1.65 to 3.6V).

Remove solder bridge to use VBAT
Connect Battery to here

The general operating range of VBAT is provied in Table 16 of the UM to be 1.65 to 3.6V. Table 13 states the maximum volatage on VBAT is 4.0V... so no LIPO directly connected.

Maximum volatge

Setup project in CubeMX

RCC and RTC

The Nucelo has a crystal resonators installed for use as the LSE, we just need to enable it. This is done but first selecting it in the RCC grounp in the Pinout Tab as the LSE then selecting it as a clock source in the clock configuration tab.
The following shows the two selections: LSE in RCC section and enabling the RTC in the RTC section.

RCC, select the LSE and enable the RTC

Clock Configuration

Once the LSE is been set in the Pinout it can be choosen as a source for the RTC in the Clock Configuration tab.

Clock configuration, select the LSE

Generate the code

That is it for CubeMX, now we can generate the code and open the projct to make it do something.

Click generate source code

Complete the CubeMX generated code

The following code is basic test that

  • Initialise the hardware
  • Check is time is set (present in backup registers) if not Set the time
  • Read the time
YOu are free to add a UART of somehting to display the time, but this is not the purose of this tutorial.

The code, taken from ST example, just used CubeMX to generate the hardware initilisation and their code for the application. It can be found in the CubeF4 firmare folder (used to generate the project). THe main parts are repeated here because easier to copy and paste from here.

add into private variables

uint8_t aShowTime[50] = {0};
uint8_t aShowDate[50] = {0};

add into function prototypes

static void RTC_CalendarConfig(void);
static void RTC_CalendarShow(uint8_t* showtime, uint8_t* showdate);

Add into Main:

/*##-2- Check if Data stored in BackUp register1: No Need to reconfigure RTC#*/
  /* Read the BackUp Register 1 Data */
  if(HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR1) != 0x32F2)
  {  
    /* Configure RTC Calendar */
    RTC_CalendarConfig();
  }

Add into while loop:

/*##-3- Display the updated Time and Date ################################*/
    RTC_CalendarShow(aShowTime, aShowDate);  

Add to main.c with the other functions.

static void RTC_CalendarConfig(void)
{
  RTC_DateTypeDef sdatestructure;
  RTC_TimeTypeDef stimestructure;
  /*##-1- Configure the Date #################################################*/
  /* Set Date: Tuesday April 14th 2015 */
  sdatestructure.Year = 0x15;
  sdatestructure.Month = RTC_MONTH_APRIL;
  sdatestructure.Date = 0x14;
  sdatestructure.WeekDay = RTC_WEEKDAY_TUESDAY;
  
  if(HAL_RTC_SetDate(&RtcHandle,&sdatestructure,RTC_FORMAT_BCD) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler(); 
  } 
  
  /*##-2- Configure the Time #################################################*/
  /* Set Time: 02:00:00 */
  stimestructure.Hours = 0x02;
  stimestructure.Minutes = 0x00;
  stimestructure.Seconds = 0x00;
  stimestructure.TimeFormat = RTC_HOURFORMAT12_AM;
  stimestructure.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  stimestructure.StoreOperation = RTC_STOREOPERATION_RESET;
  
  if(HAL_RTC_SetTime(&RtcHandle,&stimestructure,RTC_FORMAT_BCD) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler(); 
  }
  
  /*##-3- Writes a data in a RTC Backup data Register1 #######################*/
  HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR1, 0x32F2);
}
static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate)
{
  RTC_DateTypeDef sdatestructureget;
  RTC_TimeTypeDef stimestructureget;
  
  /* Get the RTC current Time */
  HAL_RTC_GetTime(&RtcHandle, &stimestructureget, RTC_FORMAT_BIN);
  /* Get the RTC current Date */
  HAL_RTC_GetDate(&RtcHandle, &sdatestructureget, RTC_FORMAT_BIN);
  
#ifdef DISPLAY_ON_DEBUGGER
  /* Display time Format: hh:mm:ss */
  sprintf((char*)showtime,"%02d:%02d:%02d",stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
  /* Display date Format: mm-dd-yy */
  sprintf((char*)showdate,"%2d-%2d-%2d",sdatestructureget.Month, sdatestructureget.Date, 2000 + sdatestructureget.Year);
#endif
}

The Output

Run your deugger and make sure get to the end. Read the time for the variable.

Conclusion

The guide has stepped through the process of creating a project to set up the RTC on the STM32F4. Just another perpihal include in these low cost Nucleo baords have proven to be are very powerful and convenient for a number of my projects and hope this guide will help you to realse the same.

Any questions or suggestions feel free use the contact me.

Reference

The following are the documents referenced in this guide and the key documents for any project using this STM32L476 microprocessor.