cancel
Showing results for 
Search instead for 
Did you mean: 

RTC time greater than 24 hours

AlfRomeo
Associate III

Hello everyone, I am using an internal RTC on STM32L431. After running for 23:59:59 seconds, the time changes to 24:00:00 instead of 00:00:00, and the week day has not been incremented. Why is this?

14 REPLIES 14

Because the phenomenon disappears after power off reset, no difference can be seen when reading the register

This is an English language forum. 

JW

@AlfRomeo wrote:
the time continued to run after 24:00:00 seconds and changed to 00:00:00 after 39:59:59 seconds, 

Which is exactly the symptom described in @waclawek.jan's link

 


@AlfRomeo wrote:

I don't know why, but after resetting after a power outage, it improved again. 


That could suggest uninitialised data.

Or perhaps data corruption.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
Gaurangthaker
Associate II

We are using the STM32U5 MCU and its internal RTC in our project.
We are facing an issue where the RTC time sometimes goes beyond 24 hours — for example, we observed a timestamp showing 37 hours.

The RTC is configured in 24-hour format, and we have initialized the RTC and its time format correctly as per the reference manual and HAL documentation.

The main challenge is that this does not happen consistently. We see such out-of-range values only randomly, which makes it difficult to identify the root cause.

Has anyone faced a similar issue with the STM32U5 RTC? Could you please suggest possible causes or solutions, or any checks we should perform to debug this behavior?

Because it's been so long, I've forgotten how I set it up back then. The problem seems to stem from the difference in settings between the `RTC_FORMAT_BIN` and `RTC_FORMAT_BCD` parameters, which led to different results. Also, the modulo operation is very important. I'm providing the code for your reference; the code might be incorrect, but it's for informational purposes only.

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};
  RTC_AlarmTypeDef sAlarm = {0};

  /* USER CODE BEGIN RTC_Init 1 */

  /* USER CODE END RTC_Init 1 */

  /** Initialize RTC Only
  */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  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 = 8;
  sTime.Minutes = 5;
  sTime.Seconds = 0;
  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_MONDAY;
  sDate.Month = RTC_MONTH_AUGUST;
  sDate.Date = 2;
  sDate.Year = 24;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
  {
    Error_Handler();
  }

  /** Enable the Alarm A
  */
  sAlarm.AlarmTime.Hours = 8;
  sAlarm.AlarmTime.Minutes = 5;
  sAlarm.AlarmTime.Seconds = 1;
  sAlarm.AlarmTime.SubSeconds = 0;
  sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
  sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS
                              |RTC_ALARMMASK_MINUTES;
  sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
  sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
  sAlarm.AlarmDateWeekDay = 1;
  sAlarm.Alarm = RTC_ALARM_A;
  if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */
  __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
  if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)
  {
    Error_Handler();
  }
  myRun.clock.sdatestructureget = sDate;
  myRun.clock.stimestructureget = sTime;
  /* USER CODE END RTC_Init 2 */

}
void getTimeLocal(void)
{
  HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
  HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
}
static void dispCalender(RTC_DateTypeDef GetData, RTC_TimeTypeDef GetTime)
{
  getTimeLocal();
  // Displayed on the LCD screen.
  _intDisplayFix((int)(GetData.Year % 100), 17, 2, false); // year
  PutCharDot(18);
  _intDisplayFix(GetData.Month, 19, 2, false); // month
  _intDisplayFix(GetData.Date, 21, 2, false);  // day
  _intDisplayFix(GetTime.Hours, 25, 2, false); // hour
  PutCharDot(26);
  _intDisplayFix(GetTime.Minutes, 27, 2, false); // min
  _intDisplayFix(GetTime.Seconds, 3, 2, false);  // sec
}
void rtc_getCalendarTime(RTC_C_Calendar *rtc)
{
  RTC_DateTypeDef LocalData;
  RTC_TimeTypeDef LocalTime;
  HAL_RTC_GetTime(&hrtc, &LocalTime, RTC_FORMAT_BIN);
  HAL_RTC_GetDate(&hrtc, &LocalData, RTC_FORMAT_BIN);
  rtc->stimestructureget.Seconds = LocalTime.Seconds % 60;
  rtc->stimestructureget.Minutes = LocalTime.Minutes % 60;
  rtc->stimestructureget.Hours = LocalTime.Hours % 24;
  rtc->sdatestructureget.Date = LocalData.Date;
  rtc->sdatestructureget.Month = LocalData.Month;
  rtc->sdatestructureget.Year = LocalData.Year;
  rtc->sdatestructureget.WeekDay = LocalData.WeekDay;

  return;
}
/* RTC second interrupt */
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{
  static int sec_cnt = 0;
  if (hrtc->State == HAL_RTC_STATE_READY)
    rtc_getCalendarTime(&myRun.clock);
  triggerLcdUpdate(1); // Trigger LCD refresh
}

1.png2.png

My program's function is to display the current time on the LCD screen in real time every second, and the `dispCalender()` function should be called once every second. For your reference only!