2022-09-05 11:02 AM
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(×tamp);
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;
}
Solved! Go to Solution.
2022-09-05 11:46 AM
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
2022-09-05 11:46 AM
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
2022-09-06 12:05 PM
Thank you @Community member. That solved it!