3
\$\begingroup\$

I am working on stm32l053 (nucleo 64) and I want to track time with integrated RTC. Since I am quite new to stm32 development I am using CubeMX and HAL libraries.

My problem is that the time is not changing over time, the HAL_RTC_GetTime() function is always returning time that was configured at the beginning in the MX_RTC_Init() function generated by CubeMX.

Here is my code for testing: Vars:

RTC_TimeTypeDef currTime = {0};

in while

    while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      HAL_RTC_GetTime(&hrtc, &currTime, RTC_FORMAT_BIN);
      char timeBuff[20];
      sprintf(timeBuff,"%d,,,%d...%d\n", currTime.Hours, currTime.Minutes, currTime.Seconds);
      HAL_UART_Transmit(&huart2, timeBuff, sizeof(timeBuff), 100);
      HAL_Delay(1000);


  }

And here is the generated MX_RTC_Init() function:

static void MX_RTC_Init(void)
{

  /* USER CODE BEGIN RTC_Init 0 */

  /* USER CODE END RTC_Init 0 */

  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};

  /* USER CODE BEGIN RTC_Init 1 */

  /* USER CODE END RTC_Init 1 */
  /** Initialize RTC Only 
  */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_12;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN Check_RTC_BKUP */

  /* USER CODE END Check_RTC_BKUP */

  /** Initialize RTC and set the Time and Date 
  */
  sTime.Hours = 10;
  sTime.Minutes = 15;
  sTime.Seconds = 0;
  sTime.TimeFormat = RTC_HOURFORMAT12_PM;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_SATURDAY;
  sDate.Month = RTC_MONTH_MAY;
  sDate.Date = 25;
  sDate.Year = 19;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
  {
    Error_Handler();
  }
  /** Enable the WakeUp 
  */
  if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */

  /* USER CODE END RTC_Init 2 */

}

Serial output is:

10,,,15...0
10,,,15...0
10,,,15...0
10,,,15...0
10,,,15...0
10,,,15...0
10,,,15...0
10,,,15...0
10,,,15...0
10,,,15...0
10,,,15...0
.
.
.

PS. RTC WakeUp is working as expected so the RTC is counting but I guess it is not storing counts in registers.

\$\endgroup\$

4 Answers 4

7
\$\begingroup\$

The solution is to call both GetTime and GetDate at the same time, If you call only GetTime it does not update correctly:

HAL_RTC_GetTime(&hrtc, &currTime, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &currDate, RTC_FORMAT_BIN);

I don't know how they are connected, even more so because GetDate() is run after GetTime() and it still makes difference.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Indeed, if you read the programmer's manual you will find that there is a consistency lock between the time and date, the values are sampled and frozen in hardware and will not change again until both are read. Presumably this is to make sure that you don't read a time value just before midnight on Monday and then read the date just after midnight and from that mistakenly conclude that it is just before midnight on Tuesday... \$\endgroup\$ May 15, 2020 at 17:47
0
\$\begingroup\$

It looks, like clocking for RTC is not enabled (CubeMX generated code sometimes "forgets" to do that). Try adding __HAL_RCC_RTC_ENABLE() to your MX_Init function.

\$\endgroup\$
5
  • \$\begingroup\$ Thanks for suggestion, I am currently away but I will try it as soon as possible. \$\endgroup\$
    – Robert
    May 28, 2019 at 11:04
  • \$\begingroup\$ Unfortunately, it does not work even after adding that line of code. I am guessing the oscilator is working because RTC WakeUp is working as expected. \$\endgroup\$
    – Robert
    May 29, 2019 at 20:00
  • \$\begingroup\$ I suggest you try using debugger (st-link), set a breakpoint after the MX_RTC_Init() function and check the RTC register values. \$\endgroup\$
    – stiebrs
    May 30, 2019 at 12:42
  • \$\begingroup\$ I checked RTC_TR_HT, RTC->TR registers and it stays at default value even after RTC_init() Which is strange because the time that gets repeated is exactly the time that was configured in the RTC_Init(). Maybe I am looking at the wrong register... I cannot seem to find any good example of setting up RTC without HAL so I could try it out that way. \$\endgroup\$
    – Robert
    May 30, 2019 at 13:40
  • \$\begingroup\$ It turns out you have to call HAL_RTC_GetTime(&hrtc, &currTime, RTC_FORMAT_BIN); HAL_RTC_GetDate(&hrtc, &currDate, RTC_FORMAT_BIN); Both at the same time, otherwise only subsecconds get updated. \$\endgroup\$
    – Robert
    May 30, 2019 at 19:08
0
\$\begingroup\$

Met the same problem today on my own STM32L072 board. Finally found out LSE is not working, so does the RTC part. The board has a slow start up period because it will switch to LSI after some waiting time.

Change to another board, RTC works fine.

\$\endgroup\$
1
  • \$\begingroup\$ May I ask how you found that out? We're currently having issues with our RTC on some boards (TR is not counting up and WakeUp IRQ does not fire)? :) \$\endgroup\$ Mar 5, 2021 at 11:50
0
\$\begingroup\$

The STM32 RTC locks (freezes) the RTC when you read the time register and un-freezes it when you read the date register. This is done to protect you from the situation where you read the time just before midnight (e.g. 23:59:59) and then the RTC date rolls over to the next day before you read it which would result in an off-by-one-day error.

So read the time register, then read the date register.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.