cancel
Showing results for 
Search instead for 
Did you mean: 

Unix epoch timestamp to RTC

Ken CK
Associate II
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
3 REPLIES 3
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
Up vote any posts that you find helpful, it shows what's working..
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
Lead
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.