Unexpectedly fast ticks using Timer2?

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

I set up some code to count seconds using timer2 on an ATMega168(i would have used timer 1/0 but they don't wake up the avr in sleep mode apparently).

I'm running off a 4Mhz crystal and i thought that i could conveniently do:

1. Prescale by 256
2. CTC on 125
3. Second counter increments up to 125
4. Second counter clears and seconds increment, etc

So, i wrote up the register code and this is what i came up with. As a result (trying a basic count down timer using these settings), the seconds rack up about 200 times faster than they should do. Doing the maths, around 200 per second at 125*125 gets near on 4Mhz anyway, let alone a prescaler!

void timer2_init(void)
{	
	ASSR |= (1 << AS2);
	//Set timer 2 to CTC mode
	TCCR2A |= (1 << WGM21);
	//Set the timer 2 compare value (A) to interrupt every 125 ticks
	OCR2A = 125;
	//Set clock frequency to external crystal, prescaled to 256
	TCCR2B |= (1 << CS22) | (1 << CS21);
	//Set the interrupts to enable on match
	TIMSK2 |= (1 << OCIE2A);
}

ISR(TIMER2_COMPA_vect)
{
  //1/125 milliseconds
  millisecond_counter++;
  //Run every second
  if(millisecond_counter == 125)
  {
	millisecond_counter = 0;
        //run some code, update some variables, etc
  }
		
}

I was basing this from a combination of the newbie guide to timers and this implementation of a RTC:

http://www.shapeshifter.se/2009/...

I set the AS2 bit to clock from the crystal on TOSC1 (as if i were using a watch crystal, but a lot faster) so in theory this should work.

How does this work if my CPU frequency is also clocking from the crystal? I've managed to get it to get a rough second timer by putting in a 1024 prescaler and having the second counter to go up to around 5000 but something is going wrong somewhere because that would imply it's clocking much faster than the CPU which is - obviously - impossible.

Last Edited: Sun. Sep 27, 2009 - 03:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is it possible you meant to write OCR2A where it says OCR1A?

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

Ooh, nice catch!

It's still running a bit fast though, perhaps 1.5x too fast? But, nowhere near as bad as it was. I guess i could tweak it, but that would seem like fudging when it should come out accurately.

I dunno if it's the crystal or just the code though.

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

Have you set the fuses to actually use the crystal as the clock source?

What do you see when you look at the CLKO pin after setting the CLKOUT fues?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Yep it's definitely running from the crystal - i had a moment of panic when i couldn't program the chip and then i realised it was because i hadn't plugged in anything to the XTAL pins. Plus i've got a delay library that requires you to set the CPU frequency (i.e. 4MHz) and it's working.

Using the 256, 125, 125 divisors it gives an almost right counter, but not quite, so it's as if it's definitely using the crystal but perhaps it's not as accurate as it should be?

EDIT: I just checked the timing, it's actually leading by a couple of seconds a minute. Set to a four second interval it gives: 4,4,4,4,5,4,4,4,4,4,4,5,4,4. Seems like quite a large error? I was expecting seconds an hour..

Last Edited: Sun. Sep 27, 2009 - 04:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Crystals are rarely that far off. I would look for something else.

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

Whiternoise wrote:
Yep it's definitely running from the crystal - i had a moment of panic when i couldn't program the chip and then i realised it was because i hadn't plugged in anything to the XTAL pins. Plus i've got a delay library that requires you to set the CPU frequency (i.e. 4MHz) and it's working.
I am confused. You clock the whole chip from an external crystal? Then this is wrong and the cause of the error:
Quote:
ASSR |= (1 << AS2);

An additional error is introduced by this:
   //Set the timer 2 compare value (A) to interrupt every 125 ticks
   OCR2A = 125; 

For one interrupt every 125 clocks you need to load 124 into OCR2A.

Stefan Ernst

Last Edited: Sun. Sep 27, 2009 - 04:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When you say that far off, as in i should get another crystal or a new clock method entirely?

On the package it does say 4.000 so i would at least expect that kind of accuracy.

Yeah, the chip is clocked externally. I guess i should leave it as zero then?

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

Quote:
I set the AS2 bit to clock from the crystal on TOSC1 (as if i were using a watch crystal, but a lot faster) so in theory this should work.

Wrong. The frequency on the TOSC pins must be less than 1/4 the of the CPU frequency. But if you are using a 4MHz CPU frequency, then why would you need to use the asynchronous feature of the timer? Just use the CPU frequency directly.

Regards,
Steve A.

The Board helps those that help themselves.