cancel
Showing results for 
Search instead for 
Did you mean: 

How to generate a timestamp from real-time-clock (RTC)?

Member
Associate III

Also, how to receive this timestamp?

7 REPLIES 7
awiernie
Senior II

Do you need seconds or also microseconds?

Is a number sufficient or should it be a text string?

I use a C++ class, but the code should work with C, too:

with

std::time_t t;

uint32_t microseconds;

For storage I convert time_t to uint32_t

I use this code:

/* we use mktime here

If you look at the code, it does not really look very clean and breaks some coding rules,

see https://code.woboq.org/userspace/glibc/time/mktime.c.html

but as it is used for 50 years now, we assume it is quite tested.

*/

RTC_TimeTypeDef ti;

RTC_DateTypeDef da;

(void) HAL_RTC_GetTime(&hrtc, &ti, RTC_FORMAT_BIN);

(void) HAL_RTC_GetDate(&hrtc, &da, RTC_FORMAT_BIN);

struct tm tim = {0};

tim.tm_hour = ti.Hours;

tim.tm_min = ti.Minutes;

tim.tm_sec = ti.Seconds;

tim.tm_year = da.Year+100;

tim.tm_mon = da.Month -1;

tim.tm_mday = da.Date;

tim.tm_isdst = 0;

if (ti.DayLightSaving == RTC_DAYLIGHTSAVING_SUB1H)

{

tim.tm_isdst = -1;

}

else if (ti.DayLightSaving == RTC_DAYLIGHTSAVING_ADD1H)

{

tim.tm_isdst = 1;

}

t = mktime(& tim);

/* HAL: Second fraction ratio * time_unit= [(SecondFraction-SubSeconds)/(SecondFraction+1)] * time_unit */

microseconds = 1000000 * (ti.SecondFraction - ti.SubSeconds) / (ti.SecondFraction + 1);

}

I need it in seconds, and a number is sufficient enough.

awiernie
Senior II

> Also, how to receive this timestamp?

Do you mean to write it back into RTC?

RTC_TimeTypeDef tTime;

RTC_DateTypeDef tDate;

std::tm * ptm = std::localtime(&t);

if (ptm)

{

tTime.Hours = uint8_t(ptm->tm_hour);

tTime.Minutes = uint8_t(ptm->tm_min);

tTime.Seconds = uint8_t(ptm->tm_sec);

//tTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;

tTime.StoreOperation = RTC_STOREOPERATION_RESET;

if (HAL_RTC_SetTime(&hrtc, &tTime, RTC_FORMAT_BIN) != HAL_OK)

{

Error_Handler();

}

if (ptm->tm_wday == 0)

{

tDate.WeekDay = 7;

}

else

{

tDate.WeekDay =uint8_t(ptm->tm_wday);

}

// month oct to dec would be 0x10, 0x11, 0x12 according to STM but 10, 11, 12 can also be used

// the HAL_RTC_SetDate makes a conversion if required

tDate.Month = uint8_t(ptm->tm_mon) + 1;

tDate.Date = uint8_t(ptm->tm_mday);

// year is since 1900 in tm but since 2000 in HAL_RTC_SetDate

tDate.Year = uint8_t(ptm->tm_year+1900-2000);

if (ptm->tm_isdst == 1)

{

tTime.DayLightSaving = RTC_DAYLIGHTSAVING_ADD1H;

}

else if (ptm->tm_isdst == -1)

{

tTime.DayLightSaving = RTC_DAYLIGHTSAVING_SUB1H;

}

else

{

tTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;

}

if (HAL_RTC_SetDate(&hrtc, &tDate, RTC_FORMAT_BIN) != HAL_OK)

{

Error_Handler();

}

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

}

Like for example, I would like to extract that RTC data when a button is pressed and stored that timestamp.

Which STM32?

Simply read RTC->TR followed by reading RTC->DR (unless you've set BYPSHD, in which case you don't need to read the date).

JW

The STM32 WB55 Nucleo Board, how do I do that which you stated?
uint32_t time, date;
  time = RTC->TR; // reading TR locks
  date = RTC->DR; // reading DR unlocks

I don't use the 'WB55.

JW