1 sec timer using m16. faster than expected!

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

Hi All,
I need some guidance here with a 1 sec timer that I made using mega16.
I wrote some code to display 0 to 9 on a seven seg display. The counter increments every 1 sec. Though the prescalers seem to be correct and the timing I get is quite close to 1 sec, it seems to run very slightly faster than 1 per sec. I observed that it is faster by almost 1 tick for every 8 secs or so.
The micro is clocked with a 16MHz xtal and seems to be running on it too: fuses seem to be okay since I am getting very close to 1 per sec with the prescalers used.
Question: Is it normal for the timing to be off by as much as I am getting? Considering that I am using a xtal after all, I hoped it to be a lot more accurate.

I am not using the timer in any real app as of now, but if I had to, I'd atleast like it to be accurate within say 1min for every 8 hours...
I know I could tweak the prescaler till I got accurate timing, but I don't understand why it should be required at all.
Please enlighten.

Here is my code:

#include
#include

void display(int x);
int i = 0;
int main(void){
DDRC = 0xff;

TCCR1B = (1<<CS12) | (1<<CS10);
TIMSK = (1<<OCIE1A);
sei();
OCR1A = 15246;//top value
TCCR1B |= (1<<WGM12);
	for(;;){
               display(i);
		}
}

ISR(TIMER1_COMPA_vect){
if(i<9){
i= i + 1;
}
else 
i = 0;
}

void display(int i){//display it on a seven seg at PORTC
	switch(i){
		case 0:
		PORTC= ~(0x7e);
		break;
		case 1:
		PORTC= ~(0x18);
		break;
		case 2:
		PORTC= ~(0x6d);
		break;
		case 3: 
		PORTC= ~(0x3d);
		break;
		case 4:
		PORTC= ~(0x1b);
		break;
		case 5:
		PORTC= ~(0x37);
		break;
		case 6:
		PORTC= ~(0x77);
		break;
		case 7: 
		PORTC= ~(0x1c);
		break;
		case 8:
		PORTC= ~(0xff);
		break;
		case 9:
		PORTC= ~(0x1f);
		break;
		default:
		break;
	}

}

Thanks in advance,
Aashish

-Aashish.
If you don't see it coming, you'll never know what hit you...

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

I'm slightly surprised that it works at all.
ALL variables shared between ISR's and other functions (in your case 'display') need to be declared 'volatile'.
I'm referring to variable 'i' in this case.
You say 1 tick in 8 seconds? How are you defining a 'tick'?
Crystals can drift. Albeit by a small amount. You can adjust the drift by tuning the load capacitors. Double check the datasheet for the mcU.
How have you confirmed that the chip is running on the Xtal?

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

Last Edited: Sat. May 14, 2011 - 07:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is the div_8 fuse enabled or disabled ? What do you mean 1 tick for every 8 sec ? 1 tick is 1 sec, 1 uS... ?

Greg, the 'i' is different in each section since OP declared a local one in the ISR.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

Sorry, I should've been more clear.

I programmed the fuses according to the engbedded fuse calculator and haven't checked/read them again ever since (maybe about 2 months). Also, since I am getting very close to 1 increment per sec, I think that part should be covered (along with the prescaler and top value of the timer). Please correct me if I am missing something horribly important here...
I don't have a scope so I can't determine the operating frequency very accurately.

By one tick I meant one increment of the count itself and not ticks of the CPU clock. I observed something like 1 increment extra for every 8 to 9 secs.

@greg: I will remember the advice about shared variables being volatile. Just checking, is it just as simple as declaring the variable 'i' as volatile, or do I need to specify something else too?

I hope its more clear now. :-) Thanks for the prompt responses, btw.

-Aashish.
If you don't see it coming, you'll never know what hit you...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
OCR1A = 15246;//top value 

Yes, it will run faster than an interrupt every second. Redo the math.

indianajones11 wrote:
Greg, the 'i' is different in each section since OP declared a local one in the ISR.
Eh? Where do you see a local variable?

Stefan Ernst

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

I saw the int i in display() and didn't look carefully enough, ma bad.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

Just shove the word volatile in front of the declaration of 'i' and you're good to go.
Stefan has an important point about your OCR1A value. Double check your math as suggested. Perhaps you should review the timer section in your datasheet. ;)

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

aaaaarrrghhh!! What was I thinking!??
Simple division done wrongly!! :-( OCR1A should have been 15625!!
My bad!!
This is embarassing!!
@stefan: thanx for pointing that out.

-Aashish.
If you don't see it coming, you'll never know what hit you...

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

Quote:
OCR1A should have been 15625!!
Indeed :P

@Indy: No problem. I'm always posting before I've fully digested the posted code. Makes you feel silly, doesn't it :) Handy that Stefan is usually around to catch the ball when we drop it!

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

Quote:
OCR1A should have been 15625!!
Nope. 15624. ;-)

Stefan Ernst

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

i should be a char, not an int. Potential atomicity problem, but since the values don't go past nine, there is no problem. As soon as the value exceeds 255, then there's a problem.

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

gregsmithcts wrote:
Makes you feel silly, doesn't it
Something like that . :shock:

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1