Time and Time Again

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wanted to give my device a nice, accurate sense of time from this cute 10PPM crystal. So I set up a 16 bit timer to count half-microseconds.

When it overflows, it increments unsigned int in memory.

To see what time it is, program just takes the memory variable, shifts it left 16 bits and ors in the count in the counter.

Let's see, that's good for, um 2^32/2000000 or 2147 and a half seconds? Hmm. Not long enough.

Ok, we'll make the variable in memory 32 bits and return the time in a 64 bit number. That'd be good for (figure figure figure) (2^48)/2000000 is 140737488.4 seconds, and that's 39093 hours (and a few minutes) and that's 1,628 days, and that's almost 4 1/2 years.

Think anybody's going to leave their train running for 4 1/2 years? Should suffice! Well, actually, this kind of thinking caused a rude surprise the morning of the 32768th day since Jan 1, 1900 when people went to work and discovered their UNIX systems had headaches.

#include 

void StartTimer5()
{
	TCD5.CTRLA = 0 ;
	TCD5.CTRLB =  TC45_WGMODE_SINGLESLOPE_gc ;
	TCD5.CTRLC = 0 ;
	TCD5.CTRLD = 0 ;
	TCD5.CTRLE = 0 ;
	TCD5.CTRLF = 0 ;
	TCD5.INTCTRLA = 1 ; // Low level interrupt on overflow
	TCD5.INTCTRLB = 0 ;
	TCD5.CTRLGCLR = 255 ;
	TCD5.CTRLHCLR = 255 ;
	if (F_CPU == 2000000) TCD5.CTRLA = 1 ; // Count 2000000 per sec
	if (F_CPU == 4000000) TCD5.CTRLA = 2 ; // Clock/2 for 4MHz
	if (F_CPU == 8000000) TCD5.CTRLA = 3 ; // Clock/4 for 8MHz
	if (F_CPU == 16000000) TCD5.CTRLA = 4 ; // Clock/8 for 16MHz
	if (F_CPU == 32000000) TCD5.CTRLA = 4 ; // Clock/8 for 32MHz?!? (Don't have a clock/16)
	
}

volatile uint32_t TickOver = 0 ;

ISR(TCD5_OVF_vect)
{
        TCD5.INTFLAGS = TCD5.INTFLAGS;
	TickOver += 1 ;
}

uint64_t WhatTimeItIs(void)
{
	uint64_t TimeItIs;
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
	{
		TimeItIs = ((uint32_t)TCD5.CNT) + ((uint32_t) TickOver<<16);
	}	
	TimeItIs = TimeItIs >> 1 ;
	if (F_CPU == 32000000) TimeItIs = TimeItIs >> 1 ; // Counts too fast at 32MHz
	return TimeItIs ;
}

WhatTimeItIs returns in microseconds, just for convenience.

If you use this, don't forget to enable low level interrupts with PMIC.CTRL = 1. Of course, in your app, you might need higher level ints enabled too.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fortunately in the few boards I needed RTC I could afford to pop a DS32MHz oscillator on the board until the DS3231 (or 32) came out and I now use that. :-)

The boards will likely have some issues in about 87 years when the century clicks over, they will have to dig me up to sue me by then. :lol:

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cute part. I'll try to remember it when I need something more accurate that actually knows the time and date.

Right. Like I don't even remember asking the same question before on the freaks!

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut.