Skip to main content
MD'Si.1
Associate III
September 5, 2022
Solved

RTC setting off by one hour when setting the time

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;
}

This topic has been closed for replies.
waclawek.jan
waclawek.janBest answer
Super User
September 5, 2022

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

2 replies

waclawek.jan
waclawek.janBest answer
Super User
September 5, 2022

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

MD'Si.1
MD'Si.1Author
Associate III
September 6, 2022

Thank you @Community member​. That solved it!