cancel
Showing results for 
Search instead for 
Did you mean: 

RTC backup date and time

MMerc.1
Senior

Hi,

I created this function in order to store the date and time. It works !

But the problem is when I load date and time, the time is the last before turning off the system.

void RTC_Init(void)
{
	/* Restore the date form backup registers */
	RTC_LoadDateTimeFromBkpReg();
 
	HAL_RTC_SetDate(&hrtc, &currentDate, RTC_FORMAT_BIN);
	HAL_RTC_SetTime(&hrtc, &currentTime, RTC_FORMAT_BIN);
 
	/* Get the date in order to allow HAL to check if a day is elapsed and update the date if it is necessary */
	HAL_RTC_GetTime(&hrtc, &currentTime, RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc, &currentDate, RTC_FORMAT_BIN);
}
 
void RTC_StoreDateTimeIntoBkpReg(void)
{
	uint32_t dateToStore;
	uint32_t timeToStore;
	memcpy(&dateToStore, &currentDate, sizeof(dateToStore));
	memcpy(&timeToStore, &currentTime, sizeof(timeToStore));
 
	HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, (dateToStore >> 16));
	HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, (dateToStore & 0xFFFF));
	HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, (timeToStore >> 16));
	HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, (timeToStore & 0xFFFF));
}
 
void RTC_LoadDateTimeFromBkpReg(void)
{
	uint32_t dateToStore;
	uint32_t timeToStore;
 
	dateToStore = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1);
	dateToStore |= (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) << 16);
	timeToStore = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);
	timeToStore |= (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2) << 16);
 
	memcpy(&currentDate, &dateToStore, sizeof(dateToStore));
	memcpy(&currentTime, &timeToStore, sizeof(timeToStore));
}
 
void Update_DateTime(void)
{
	HAL_RTC_GetTime(&hrtc, &currentTime, RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc, &currentDate, RTC_FORMAT_BIN);
 
	RTC_StoreDateTimeIntoBkpReg();
}

How can I configure this to update date and time with VBat ?

Best regards

4 REPLIES 4

I don't understand. When do you call these functions? Why do you call them at all?

If you don't touch the RTC at all (i.e. you don't "initialize" it after reset), it will run properly as long as there's voltage on VBAT.

JW

PS. Which STM32?

Hi,

I am using the STM32F746BGT.

I am based on this post.

"RTC_Init" is called in the main function :

int main(void)
{
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_RTC_Init();
  [...]
 
  /* USER CODE BEGIN 2 */
  RTC_Init();
 
  /* Call init function for freertos objects (in freertos.c) */
  MX_FREERTOS_Init(); 
  /* Start scheduler */
  osKernelStart();
}

"RTC_Init" calls the "RTC_LoadDateTimeFromBkpReg" function.

"Update_DateTime" is called every second (in a task with FreeRTOS).

"Update_DateTime" calls the "RTC_StoreDateTimeIntoBkpReg" function.

PS : I have not modify the "MX_RTC_Init" function.

/* RTC init function */
void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};
 
  /** 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.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 = 0;
  sTime.Minutes = 0;
  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_SATURDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 1;
  sDate.Year = 0;
 
  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
  {
    Error_Handler();
  }
 
}

Best regards

That post is 'F1xx-specific. 'F1xx has a different RTC, and the rather cumbersome SPL and CUbe/HAL library functions for the 'F1xx did not track date for reasons to me unknown, so that users invented various workarounds for that.

'F7xx has a normal RTC and you don't need to store/restore time/date. SImply set it up once, and then just read the time/date from it, even after power reset. As long as battery is connected to VBAT, RTC will provide correct time/date.

JW

Hi,

I am using the following code now :

int main(void)
{
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_RTC_Init();
  [...]
 
  /* USER CODE BEGIN 2 */
  Update_DateTime();
 
  /* Call init function for freertos objects (in freertos.c) */
  MX_FREERTOS_Init(); 
  /* Start scheduler */
  osKernelStart();
}
 
void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};
 
  /** 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.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 = 0;
  sTime.Minutes = 0;
  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_SATURDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 1;
  sDate.Year = 0;
 
  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
  {
    Error_Handler();
  }*/
 
}
 
void Update_DateTime(void)
{
	HAL_RTC_GetTime(&hrtc, &currentTime, RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc, &currentDate, RTC_FORMAT_BIN);
}

"Update_DateTime" is called every second (in a task with FreeRTOS).

As you said, there is no need to store/restore date and time. But when I turn off the system for 30 minutes then wake it up, the time is the time before turning off the system.

Do I have to set "Store Operation" to "Storeoperation set" (it is currently on "Storeoperation reset") ?

Best regards