cancel
Showing results for 
Search instead for 
Did you mean: 

RTC setting off by one hour when setting the time

MD'Si.1
Associate III

Hi,

I am setting my RTC with a timestamp and when I read it back immediately I notice the hour setting is always off by 1 hour. I do not have daylight savings mode enabled on the RTC and I cannot understand why the hour setting is off. I thought the issue had to do with Daylight Savings and tried both the Add1H and Sub1H settings for the RTC but those did not have any effect on the issue.

Here is the log of my testing:

Write Time - 1662156522   (Timestamp is 02-09-2022 / 22:08:42)
 
After converting from timestamp 22:08:42  (Timestamp converted just before setting RTC)
 
02-09-2022 / 21:08:56  (Read Time ())

My RTC init()

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_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 */
  
  if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != CALENDAR_INITIALIZED)
  {
  
    /* Write magic value RTC Backup data Register0 */
    HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, CALENDAR_INITIALIZED);
  /* 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();
  }
  /** Enable the WakeUp
  */
  __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
  if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 300, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */
  
  }
  
 
  //Disable the Wakeup Timer on boot
  if (HAL_RTCEx_DeactivateWakeUpTimer(&hrtc))
  {
    Error_Handler();
  }
  /* USER CODE END RTC_Init 2 */
 
}

My Set time ()

void RtcUTimeUpdateSntp(time_t timestamp)
{
  RTC_DateTypeDef sdatestructure;
  RTC_TimeTypeDef stimestructure;
  struct tm ts;
  char temp[2] = {0, 0};
 
  /* convert SNTP time (seconds since 01-01-1900 to 01-01-1970)
 
  EPOCH_TIME_DIFF is equivalent to 70 years in sec
  calculated with www.epochconverter.com/date-difference
  This constant is used to delete difference between :
  Epoch converter (referenced to 1970) and SNTP (referenced to 1900) */
 
  /* convert time in yy/mm/dd hh:mm:sec */
  ts = *localtime(&timestamp);
  ts.tm_isdst=1; 	//indicate DST is in effect
 
  printf("After converting from timestamp %02d:%02d:%02d\r\n",ts.tm_hour,ts.tm_min, ts.tm_sec);
 
  /* convert date composants to hex format */
  sprintf(temp, "%ld",  (unsigned long)(ts.tm_year - 100));
  sdatestructure.Year = strtol(temp, NULL, 16);
  sprintf(temp, "%ld", (unsigned long) (ts.tm_mon + 1));
  sdatestructure.Month = strtol(temp, NULL, 16);
  sprintf(temp, "%d", ts.tm_mday);
  sdatestructure.Date = strtol(temp, NULL, 16);
  /* dummy weekday */
  sdatestructure.WeekDay =0x00;
 
  if (HAL_RTC_SetDate(&hrtc, &sdatestructure, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  /* convert time composants to hex format */
  sprintf(temp,"%d", ts.tm_hour);
  stimestructure.Hours = strtol(temp, NULL, 16);
  sprintf(temp,"%d", ts.tm_min);
  stimestructure.Minutes = strtol(temp, NULL, 16);
  sprintf(temp, "%d", ts.tm_sec);
  stimestructure.Seconds = strtol(temp, NULL, 16);
  stimestructure.DayLightSaving=1;
  if (HAL_RTC_SetTime(&hrtc, &stimestructure, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
 
}

My Read Time ()

uint64_t RtcUGetTimeUnix(void)
{
  RTC_TimeTypeDef RTC_Time;
  RTC_DateTypeDef RTC_Date;
 
  HAL_RTC_GetTime(&hrtc,&RTC_Time,RTC_FORMAT_BCD);
  HAL_RTC_GetDate(&hrtc,&RTC_Date,RTC_FORMAT_BCD);
 
 
  printf("%02x-%02x-20%02x / %02x:%02x:%02x\r\n",\
        RTC_Date.Date, RTC_Date.Month, RTC_Date.Year,RTC_Time.Hours,RTC_Time.Minutes,RTC_Time.Seconds);
 
 
  HAL_RTC_GetTime(&hrtc,&RTC_Time,RTC_FORMAT_BIN);
  HAL_RTC_GetDate(&hrtc,&RTC_Date,RTC_FORMAT_BIN);
 
  uint8_t hh = RTC_Time.Hours;
  uint8_t mm = RTC_Time.Minutes;
  uint8_t ss = RTC_Time.Seconds;
  uint8_t d = RTC_Date.Date;
  uint8_t m = RTC_Date.Month;
  uint16_t y = RTC_Date.Year;
  uint16_t yr = (uint16_t)(y+2000-1900);
 
  struct tm tim = {0};
  tim.tm_year = yr;
  tim.tm_mon = m - 1;
  tim.tm_mday = d;
  tim.tm_hour = hh;
  tim.tm_min = mm;
  tim.tm_sec = ss;
 
  time_t currentTime = {0};
  currentTime = mktime(&tim);
 
  /*
  tim = gmtime(currentTime);
  currentTime = mktime()
  */
 
  /* Return number of seconds since Unix Epoch (1/1/1970 00:00:00).  */
  return (uint64_t)currentTime;
}

1 ACCEPTED SOLUTION

Accepted Solutions

In RtcUTimeUpdateSntp, fill in all sdatestructure and stimestructure fields, or initialize these structs to zero when defining as you do in MX_RTC_Init.

http://www.efton.sk/STM32/gotcha/g113.html

JW

View solution in original post

2 REPLIES 2

In RtcUTimeUpdateSntp, fill in all sdatestructure and stimestructure fields, or initialize these structs to zero when defining as you do in MX_RTC_Init.

http://www.efton.sk/STM32/gotcha/g113.html

JW

Thank you @Community member​. That solved it!