As explained in the previous answer, you forgot to account for the time
taken by the CPU to handle the interrupt prologue. As a general rule, if
you want consistent timing, you should never reset the timer by
software after the initialization.
If you want to run the timer in normal mode, and use it to schedule
interrupts at a period that is not the timer's own period, it is
possible, but you should not use the overflow interrupt for this
purpose. You should instead use any of the “compare match” interrupts,
and adjust the compare register in the IRS in order to schedule the next
interrupt. For example:
void setup() {
pinMode(14,OUTPUT);
TCCR1A = 0; // normal mode
TCCR1B = _BV(CS11); // clock @ F_CPU/8
TCNT1 = 0; // clear timer
OCR1A = 1000; // first COMPA match in 1000 cycles
TIFR1 = _BV(OCF1A); // clear interrupt flag
TIMSK1 = _BV(OCIE1A); // enable TIMER1_COMPA interrupt
}
ISR(TIMER1_COMPA_vect) {
OCR1A += 1000; // schedule next interrupt
PINJ = _BV(PJ1); // toggle PJ1 = digital 14
}
Note that the line OCR1A += 1000;
can cause a wrap around, but this is
no problem, as the addition wraps around in exactly the same way as the
timer itself.
The advantage of this technique is that you can schedule up to three
different tasks, having different periods, with only one timer. And you
can even schedule tasks in a non-periodic fashion.
That being said, if you do not need the timer for anything else other
than scheduling a single periodic task (or up to four tasks sharing the
same period), then a better solution is to let the timer handle the
period all by itself. Configure the timer in mode 12 or 14 (CTC or fast
PWM, with TOP = ICR1), and set the period with ICR1 = 999;
. Then the
ISR is reduced to:
ISR(TIMER1_COMPA_vect) { PINJ = _BV(PJ1); }
and you save a few cycles. This would be my preferred solution if I
absolutely had to output the signal on pin 14.
Note that this solution should give you the right average frequency,
but you will still have some jitter, because the interrupt can
occasionally be delayed by other interrupts. If you are free to choose
the output pin, then the best solution is to let the timer handle the
PWM generation all by itself. Set the timer to any PWM mode (fast PWM is
the simplest) and use one of the waveform generators in order to
generate the PWM signal. Only the PWM-capable pins (those marked with a
“~” symbol) can be used this way. For example, Timer 1 can output to
pins 11 (OC1A), 12 (OC1B) and 13 (OC1C).
Edit answering the question:
what is the goal of TIFR1 = _BV(OCF1A); // clear interrupt flag
?
Whenever the timer value matches the contents of the compare register
OCR1A
, the interrupt flag OCF1A
(Output Compare Flag of timer 1,
channel A) is raised. This flag controls the interrupt request when the
OCIE1A
bit (Output Compare Interrupt Enable 1A) is set. The flag is
automatically cleared when the ISR runs, and can be manually cleared by
writing a logic 1 to it (yes, it is kind of backwards).
It is quite likely that the flag raises early in the start process,
while the Arduino library is initializing. If the flag is up when you
enable the interrupt, an interrupt request is immediately triggered. In
order to avoid that, the common practice is to clear the flag before
enabling the interrupt.
TCNT1
, but you need to set the TOP value. This depends on which PWM/timer mode you use (see table in datasheet). I know it'sICR1
orOCR1A
on the UNO. Not sure about the Mega.