cancel
Showing results for 
Search instead for 
Did you mean: 

RTC losing fractions of second on uP reset - how to solve?

Peter Mather
Associate III

My code initialises the RTC using the standard CubeMX code but before setting the clock it tests for a valid year > 2018. This works perfectly and the time and date are preserved through resets of the uP.

However, it appear that either the reset or the call to HAL_RTC_Init zeroes the fractions of a second stored in the RTC registers. This can be proven by repeated resetting the processor each time withing a second which causes time to stand still.

Is there a solution to this so that the fractions of a second are preserved through resets and power cycles?

Thanks

static void MX_RTC_Init(void)
{
 
  /* USER CODE BEGIN RTC_Init 0 */
	int up=RTC_SMOOTHCALIB_PLUSPULSES_RESET;
	int calibrate= -Option.RTC_Calibrate;
  /* USER CODE END RTC_Init 0 */
 
  RTC_TimeTypeDef sTime;
  RTC_DateTypeDef sDate;
 
  /* 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 = 7;
  hrtc.Init.SynchPrediv = 4095;
  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 */
  if (HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
  {
	  Error_Handler();
  }
 
  if (HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
  {
	  Error_Handler();
  }
  RtcGetTime();
  if(sDate.Year<18){
    
  /* USER CODE END Check_RTC_BKUP */
 
  /** Initialize RTC and set the Time and Date 
  */
  sTime.Hours = 0x0;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 0x1;
  sDate.Year = 0x0;
 
  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */
  }
  if(Option.RTC_Calibrate>0){
	  up=RTC_SMOOTHCALIB_PLUSPULSES_SET;
	  calibrate=512-Option.RTC_Calibrate;
  }
  HAL_RTCEx_SetSmoothCalib(&hrtc, RTC_SMOOTHCALIB_PERIOD_32SEC, up, calibrate);
 
  /* USER CODE END RTC_Init 2 */
 
}

13 REPLIES 13
if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) {
  // start LSE and initialize RTC here
}

JW

To develop software one must be capable of... developing software. How surprising! One have to know at least the generic software design principles, C programming language and have the basic level of hardware understanding. Those are the prerequisites for these tasks! The same as you cannot go to university and ask the professors to teach you the basic arithmetic.

And, by the way, in the first link Jan posted, there is a post from me with an example code exactly for this issue...

Thanks for your help. As CubeMX loves to destroy the code, somehow I was confused, that it is not working... here is CubeMX ":friendly" variant:

RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef DateToUpdate = {0};
  /* USER CODE BEGIN RTC_Init 1 */
  hrtc.Instance = RTC;
  hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
  hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM;
	if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) {
  /* USER CODE END RTC_Init 1 */
  /** Initialize RTC Only
  */
  hrtc.Instance = RTC;
  hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
  hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN Check_RTC_BKUP */
  } else
  /* RTC int */
  {
  HAL_NVIC_SetPriority(RTC_IRQn,15,0);
  HAL_NVIC_EnableIRQ(RTC_IRQn);
  }
	if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1)!= 0x5051)
	{
  /* USER CODE END Check_RTC_BKUP */
...

I had to enable RTC interrupts manually. Also, some code is duplicated - just only to keep it from deleted by Cube.

you are smart