cancel
Showing results for 
Search instead for 
Did you mean: 

SMT32L476 RTC, subsecond register

confalonieri
Associate II
Posted on December 21, 2016 at 12:30

Hi,

Iis anyone aware how to set the RTC registers to obtain a .01s resolution using the subsecond register ?

Regards

F.c.

4 REPLIES 4
Jan Waclawek
Senior II
Posted on December 21, 2016 at 13:53

You need to use a crystal which oscillates at integer multiple of 100Hz.

JW

thomfischer
Senior
Posted on December 21, 2016 at 14:43

try

/* RTC init function */

void MX_RTC_Init(void)

{

    /**Initialize RTC Only

    */

  hrtc.Instance = RTC;

  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;

  hrtc.Init.AsynchPrediv = 31;

  hrtc.Init.SynchPrediv = 1023;

  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;

  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;

  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;

  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;

  if (HAL_RTC_Init(&hrtc) != HAL_OK)

  {

    Error_Handler();

  }

}

...

...

HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);

HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);

msec = 999 - (sTime.SubSeconds * 999 / sTime.SecondFraction);   //  sTime.SecondFraction=1023

xsprintf(line,'%04d-%02d-%02d %02d:%02d:%02d.%03d   ', (int) sDate.Year + 2000, (int) sDate.Month, (int) sDate.Date, (int) sTime.Hours, (int) sTime.Minutes, (int) sTime.Seconds, msec);

    xprintf('%s',line);

divide msec/10

Posted on December 22, 2016 at 01:56

This (768kHz LSE Xtal, PREDIV_A=31, PREDIV_S=1023) will give you millisecond (or 0.01s after dividing by 10) display; but not exactly 10ms resolution in real time.

The time between 'ticks' (i.e. between moments when the result of the 10ms calculation changes) will be 9.766ms most of the time, sometimes switching to 742ms - see attached spreadsheet. This is because the real resolution of the subsecond timer in this case is 1/(32768kHz/32)=0.977ms, and the content of subsecond timer can change only at integer multiples of this period.

Also the formula

msec = 999 - (sTime.SubSeconds * 999 / sTime.SecondFraction); // sTime.SecondFraction=1023

is slightly off, the correct formula is (see description of RTC_SSR in RM):

msec = 1000 * (PREDIV_S - RTC_RTC_SSR.SS) / (PREDIV_S + 1)

The difference is minimal in this particular case (PREDIV_S == 1023).

If higher precision of the ticks is desirable, still with the 768kHz crystal and correct RTC time, the PREDIV_A value can be decreased with compensating increase of PREDIV_S. For example, with PREDIV_A = 3 and PREDIV_S = 8191, the 10ms calculation 'ticks' alternate between 9.888ms and 010ms. The cost for this is a significantly higher change rate of the subsecond register (8.192kHz, 0.122ms period) and increased consumption.

If true RTC is not needed, only the 10ms ticks as precise as possible, still with 768kHz crystal, PREDIV_A = 82 and PREDIV_S = 399 yields a 2.502ms subsecond tick, four such ticks are uniformly 010ms then.

With a crystal per my suggestion (i.e. integer multiple of 100Hz, e.g. 40kHz is not an uncommon value) the OP's requirement can be fulfilled perfectly, if this is ultimately needed.

JW

________________

Attachments :

STM32_RTC.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hyyw&d=%2Fa%2F0X0000000bFP%2FJ9pIVZ8RODCGR_G4ILE.W0pABpxLcAv.u3_sizMpWiQ&asPdf=false
confalonieri
Associate II
Posted on December 22, 2016 at 15:55

Jan, Thomas,

Thank you. I am working testing your suggestion to find the best RTC setting for my purpose.

FC