Skip to main content
Ken CK
Associate II
January 28, 2018
Question

Unix epoch timestamp to RTC

  • January 28, 2018
  • 3 replies
  • 10372 views
Posted on January 28, 2018 at 11:48

I want to use the Unix Epoch timestamp to configure the STM32 internal RTC to keep it synced up with network time. Can you advise how I can convert/use the milliseconds since 1970 Jan 1 to be applied to the internal RTC using CubeMX+HAL libraries?

Thank you!

#stm32-stm32cube #stm32f4-cube #rtc-cube #rtc-hal #stm32-f4
This topic has been closed for replies.

3 replies

Tesla DeLorean
Guru
January 28, 2018
Posted on January 28, 2018 at 17:39

Which STM32?

32-bit UNIX time reflects seconds, not milliseconds. Milliseconds would wrap in 49 days.

You can crack UNIX time/date using gmtime(), most people would be safest using the libaray

The conversion back can be done reasonably efficiently, I used unsigned as it works beyond 2038

//****************************************************************************

unsigned int UNIXTime(int Day, int Month, int Year, int Hour, int Minute, int Second)

{

// Month 1-12   

mailto:sourcer32@gmail.com

// Year 1970-2099 (Fails >28-Feb-2100, Not a leap year, 2106 breaks 32-bit)

if (Month <= 2)

{

Year--;

Month += 12;

}

Day = ((36525 * Year) / 100) + ((306001 * (Month + 1)) / 10000) + Day - 719606;

Second += (Minute * 60) + (Hour * 3600);

return(((unsigned int)Day * (24 * 60 * 60)) + (unsigned int)Second);

}

//****************************************************************************

Most date based RTC implementations are good 1901-2099, where all DIV4 years are leap, beyond this they usually break.

The STM32F1 has a 32-bit counter RTC, I've used UNIX time directly on it.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Ken CK
Ken CKAuthor
Associate II
January 28, 2018
Posted on January 28, 2018 at 17:59

That is exactly what I was looking for, seconds will be sufficient for me.

I will need to use this on an STM32F429ZI, on an STM32F746NG and on an STM32L100RCT6.

john doe
Senior III
January 28, 2018
Posted on January 29, 2018 at 00:20

void updateRTC(time_t now)
{

 RTC_TimeTypeDef sTime;
 RTC_DateTypeDef sDate;

 struct tm time_tm;
 time_tm = *(localtime(&now));

 sTime.Hours = (uint8_t)time_tm.tm_hour;
 sTime.Minutes = (uint8_t)time_tm.tm_min;
 sTime.Seconds = (uint8_t)time_tm.tm_sec;
 if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }

 if (time_tm.tm_wday == 0) { time_tm.tm_wday = 7; } // the chip goes mon tue wed thu fri sat sun
 sDate.WeekDay = (uint8_t)time_tm.tm_wday;
 sDate.Month = (uint8_t)time_tm.tm_mon+1; //momth 1- This is why date math is frustrating.
 sDate.Date = (uint8_t)time_tm.tm_mday;
 sDate.Year = (uint16_t)(time_tm.tm_year+1900-2000); // time.h is years since 1900, chip is years since 2000

 /*
 * update the RTC
 */
 if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }

 HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,0x32F2); // lock it in with the backup registers

}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

and if you want to go the other direction,

 RTC_DateTypeDef rtcDate;
 RTC_TimeTypeDef rtcTime;
 HAL_RTC_GetTime(&hrtc, &rtcTime, RTC_FORMAT_BIN);
 HAL_RTC_GetDate(&hrtc, &rtcDate, RTC_FORMAT_BIN);
 uint8_t hh = rtcTime.Hours;
 uint8_t mm = rtcTime.Minutes;
 uint8_t ss = rtcTime.Seconds;
 uint8_t d = rtcDate.Date;
 uint8_t m = rtcDate.Month;
 uint16_t y = rtcDate.Year;
 uint16_t yr = (uint16_t)(y+2000-1900);
 time_t currentTime = {0};
 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;
 currentTime = mktime(&tim);
 struct tm printTm = {0};
 printTm = *(localtime(&currentTime));
 char buffer[80];
 strftime(buffer,80,'RTC %m/%d/%y %H:%M:%S', &printTm);
 printf('%s

', buffer);�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

When using the standard c library to do time/date math, you have two data types and function calls. localtime() lets you go from time_t, which is seconds from new years 1900, to struct tm, which is a struct with everything broken out. localtime() to go from a time_t data type to a struct tm, and mktime() to go from a struct tm data type to time_t.