Sub-second timing taken from Nucleo STM32 F0 F3 F4 RTC

The RTC hardware on the STM32's is capable of reporting sub-second timing resolution. This is not supported by the mbed HAL & API's though. However, we can make a function analogous to mbed's rtc_read() which will return the current fractional second as well as the time_t whole second time/datestamp:

Modified rtc_read() function

void rtc_read_frac_s(time_t * t, float * secfrac)
{
    RTC_HandleTypeDef RtcHandle;
    RTC_DateTypeDef dateStruct;
    RTC_TimeTypeDef timeStruct;
    struct tm timeinfo;

    RtcHandle.Instance = RTC;

    HAL_RTC_GetTime(&RtcHandle, &timeStruct, FORMAT_BIN);
    HAL_RTC_GetDate(&RtcHandle, &dateStruct, FORMAT_BIN);

    // Setup a tm structure based on the RTC
    timeinfo.tm_wday = dateStruct.WeekDay;
    timeinfo.tm_mon  = dateStruct.Month - 1;
    timeinfo.tm_mday = dateStruct.Date;
    timeinfo.tm_year = dateStruct.Year + 100;
    timeinfo.tm_hour = timeStruct.Hours;
    timeinfo.tm_min  = timeStruct.Minutes;
    timeinfo.tm_sec  = timeStruct.Seconds;

    // Convert to timestamp
    *t = mktime(&timeinfo);

// Standard granularity is ~4ms (1/256sec)
// Import mbed-dev & modify rtc_api.c's rtc_init() with these values for ~1ms (1/1024sec) granularity:
//    RtcHandle.Init.AsynchPrediv   = 0x1f;
//    RtcHandle.Init.SynchPrediv    = (rtc_freq / 0x20) - 1;

    *secfrac = ((float)(timeStruct.SecondFraction-timeStruct.SubSeconds)) / ((float)(timeStruct.SecondFraction+1));
    return;
}

Usage:

time_t time;
float frac_secs;
rtc_read_frac_s(&time, &frac_secs);

As an aside, it appears that the current Nucleos are being fitted with the LSE crystal, and the latest (as at 03/16) mbed library's RTC init has been fixed such that the time is not set to zero at every reboot.

To set the time, I've used code based on Kenji Arai's https://developer.mbed.org/users/kenjiArai/code/Nucleo_RTC_Clock_setting/


Please log in to post comments.