Jump to content

Recommended Posts

I am building an accurate clock using and external RTC module.

I am using a Launchpad MSP430F5529 25Mz and an external DS3232 RC board. (These boards have 2 or 3 ppm accuracy) With an accurate PPS tick I know the seconds time is accurate. For sub second timing I will need to use an internal counter.


I have an ISR that registers the pulse from the DS3232 SQW. This routine sets a flag (PPS) and saves the millis() value to a volatile variable only. In my main loop I wait for the PPS flag, update the time values then Serial.print the recorded millis value and the time.


The table below shows the output. The difference column (calculated post hoc) shows a regular millis() count of 989 per second.


Hence my question - how accurate is the timer used to generate millis()?


Supplementary questions:


Can the millis accuracy be improved? AND/OR

If I wanted to implement a more accurate millisecond tick what timer(s) are available to me in Energia?






millis   diff   Time String

45495         07:25:47

46484 989 07:25:48

47473 989 07:25:49

48461 988 07:25:50

49450 989 07:25:51

50439 989 07:25:52

51427 988 07:25:53

52416 989 07:25:54

53404 988 07:25:55

54393 989 07:25:56

55382 989 07:25:57

56371 989 07:25:58

57360 989 07:25:59

58348 988 07:26:00


Link to post
Share on other sites

Not too terribly accurate as you've found. It would require modifying the Energia core quite a bit to change millis() as it uses the Watchdog timer.


Jitter and drift will be caused by the main oscillator (DCO) mostly. It's not known to be all that accurate but can be trimmed. At least with the F5529 there is an FLL driven by the 32.768KHz XTAL to auto-trim it.

Link to post
Share on other sites

My data shows a consistency rather than a jitter. If I get 989 ticks in 1 second then each tick is 

0.001011122   of a second.


I can see in wiring.c that the WDT is set to fire on 8192 clock ticks so a naive calculation would suggest that 8102 ticks might be closer to the mark. I assume that there is an allowance for ISR overhead somewhere too,


I realise that this may be far too simplistic!




Link to post
Share on other sites

That is true, millis only updates when the ISR fires, so your sketch may be pulling the millis value some time "after" the last tick.


For the purpose of getting a super-accurate clock, I would look into making your "own" millis-style API using one of the Timer_A peripherals and include a direct-read of the TAxR register to compensate for between-ISR timing.  You should have free access to declare one of the Timer_A interrupt vector entries in your own sketch without Energia getting in the way.  Just be sure you're not using a PWM output pin that happens to use that same Timer_A instance or else Energia's analogWrite() call will clobber your timer settings.

Link to post
Share on other sites


Thanks. I was moving that way. No pin output is needed.


Is there a list of Timers / interrupts used by core and various libraries to see where clashes may occur as I may want to use Analog output for some audio.


As an aside I tried editing the TICKS_PER_WDT_OVERFLOW value in wiring.c, I found 8274 was closest to 1000 millis per second but still not perfect. I did look at the arithmetic in wiring.c and could not get my head around how the fractions work in an integer count.



Link to post
Share on other sites

This has been discussed before for example: http://forum.43oh.com/topic/6213-ds3231-rtc-library-for-5529/?p=68658


Not sure if the RTC counter can be accessed sub second.


In my case I am planning to use the DS3232 SQW interupt as it has 2 to 3 ppm accuracy and I have used this before on other MCUs. The RTC crystal is self compensating so nothing to worry about there.



Link to post
Share on other sites

I'm just hypothesizing here but doesn't the F5529 have an RTC within?

Makes me wonder why Energia doesn't leverage that for millis and such functions.

IIRC, it does, but only under sleep() and sleepSeconds() mode.  Higher resolution is available via DCO which is why it uses it.  Just not necessarily the best accuracy I guess...

Link to post
Share on other sites

TIMERA can take a variety of clock sources. Normally people use the internal  SMCLK or ACLK but you can also feed it an external clock. See the code below even though it is written for an msp430g2553 (TimerA are mostly the same on all chips) Take note how the clock source is set: TACTL = TASSEL_0;





Link to post
Share on other sites

I guess one problem is, the precision... only 1/32768 of a second, and the math if you need absolute milliseconds.


1/32768 = .00003051757812500000 or basically 30.517578125 ms.

Maybe my math is off, but a millisecond is one/one-thousandth (1/1000) of a second. So, the aforementioned 0.00003051757812500000 seconds is 0.030517578125 milliseconds... not 30.517578125 milliseconds.
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...