attiny84 timer 1 running fast?

This isnt really arduino related so I am posting it here, I have an attiny84 that I simply wanted a timer to trigger an innterupt every second. seems simple enough, set some bits, do some simple division, make a ISR function and done. what I am getting though is instead of of a pin change every second, is a pin change every 800ms.

I am using the internal oscilator @ 8Mhz

void setup()
{
  DDRA  = 0xDF;
  PORTA = 0x20;
  DDRB  = 0xFF;
  PORTB = 0xFF;
 
  noInterrupts();         
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 31250;            
  TCCR1B |= (1 << WGM12);   
  TCCR1B |= (1 << CS12);   
  TIMSK1 |= (1 << OCIE1A);  
  interrupts();
}

ISR(TIM1_COMPA_vect) // timer interrupt 
{
  digitalWrite(2, !digitalRead(0));
}

edit when I change fuses to output the clock on PB2, its pretty jhonny on the spot 8Mhz, I can deal with it being a little off, but not 200ms per cycle off

You seem to be setting a pre-scale of 256 so your interrupt frequency should be:

8,000,000
------------------------- = 0.499984 Hz
2 * 256 * (31250+1)

To get 1 Hz you want 2 * 256 * (OCR1A+1) == 8000000 so OCR1A = 15624

Question: Why are you reading a value from pin 0 to write (inverted) to pin 2? Could that be a problem?

ok thanks, I will give that a shot

Question: Why are you reading a value from pin 0 to write (inverted) to pin 2? Could that be a problem?

just to get a pin output for my scope, the timer is really decrementing a counter for a timer, and I was comparing the display to a metronome, but needed something a bit more concrete to explain what was going on

@johnwasser : To get a frequency you have to toggle twice, so I think your figure is out by a factor of 2.

I wouldn't be using an ISR, that adds an error amount. Although 200 mS sounds like a lot. You can set the hardware to toggle the pin.

in the final application its not toggling a pin, its doing a simple math function, it will be eventually toggling a pin but not based on the 1Hz cycle, that will be programmable, and not needed if I cant get the silly timer working.

considering this thing will be replacing a R/C network with a fet on the end (which is a awesome time saver for the engineer who twisted it together, but a major PITA for me, the guy who has to keep it going, and me, the guy who has to sit there with a calculator and multimeter tweaking a trimpot when test conditions change when I rather just hit some buttons and flip a switch) some difference is fine, 200ms though is way too much.

the formulas I have seen, and even a online calculator say that 31250 with a 256 prescaller IS 1Hz, but I am willing to try suggestions as they come in (cause I just turned in a 64 hour time sheet and really dont want to spend my Sunday farting around with trying to add a more accurate clock source on something where I am already using every pin except reset, power and ground, though I could with a single transistor ..diode..resistors.. anyway, it really should not be needed as the internal clock is pretty darn good as it is)

johnwasser:
Question: Why are you reading a value from pin 0 to write (inverted) to pin 2? Could that be a problem?

Yeah, why? Isn't the value on pin 0 going to influence this behaviour? Does that change? Every 200 mS maybe?

  OCR1A = 31250;

Remember this is zero-relative. You probably want 31249.

... and really dont want to spend my Sunday farting around with trying to add a more accurate clock source ...

Well humour us and just toggle pin 2 rather than making it depend on pin 0.

Well humour us and just toggle pin 2 rather than making it depend on pin 0.

ya know I just now caught what you guys were saying (64 hours will do that to you) thats a type-o, I just confirmed in the code that I am a moron

Ill get back with results tomorrow

and no it doesnt change every 200ms, it changes every 5ms but still, I need to correct my results before proceeding (acutally doing the math that would get rid of most of what I am seeing on the scope)

He said he wanted an interrupt every 1 second, not a 1 Hz output square wave.

Osgeld:
the formulas I have seen, and even a online calculator say that 31250 with a 256 prescaller IS 1Hz, but I am willing to try suggestions as they come in

Setting OCR1A to 31249 will get you an interrupt every 2 seconds. Are you sure the online calculators weren't written for the more common 16 MHz clock?

The formula in the datasheet for CTC (Clear Timer on Compare) mode is:

F_CPU
--------------------------------- == F(interrupt)
2 * prescale * (OCR1A+1)

Solve for OCR1A and you get:

F_CPU
--------------------------------- - 1 == OCR1A
F(interrupt)2prescale

johnwasser:
He said he wanted an interrupt every 1 second, not a 1 Hz output square wave.

That's the point isn't it? - You need to remove the 2 x from your formula.

8e6 / 256 = 31250 (timer clock pulses per second)

Assuming CTC (clear counter on compare match) mode 4:

For a 1s interval interrupt you need to set OCR1A to (31250 - 1) = 31249

For a 1Hz frequency out you need to set OCR1A to (31250/2 - 1) = 15624

BenF:

johnwasser:
He said he wanted an interrupt every 1 second, not a 1 Hz output square wave.

That's the point isn't it? - You need to remove the 2 x from your formula.

8e6 / 256 = 31250 (timer clock pulses per second)

Assuming CTC (clear counter on compare match) mode 4:

For a 1s interval interrupt you need to set OCR1A to (31250 - 1) = 31249

For a 1Hz frequency out you need to set OCR1A to (31250/2 - 1) = 15624

Oops. You're right.
The formula that I thought was for time interval was for output frequency when using the "Toggle OC1A on Reset". 31249 is the right value for a 1-second interval between interrupts.