Timer Accuracy Always off by 1uS I am using the ATMega32u4 to generate a pulse at 1 kHz. I am using Timer 3, which is a 16-bit timer and using a prescaler of 1, so I have a 0.0625uS resolution. The good news is that this is working, I can control the frequency and pulse length of the square wave. The issue is that I noticed the pulse always seems to be 1uS off.

If I set a period of 1000uS, and a pulse of 500uS, the oscilloscope shows a period of 1001uS and a pulse of 501uS. 

If I set a period of 100uS, and pulse of 10uS, the oscilloscope shows a period of 101uS, and a pulse of 11uS.





If the Timer had an error percentage, then both the period and pulse should be off by the same percentage, but there are always off by the same 1uS length. I assume I am doing something wrong, so I have posted my code below.

const int pin1 = 4;

void setup() {
  //Set pin to output
  pinMode(pin1, OUTPUT);

  // Reset Timer 3 Control Register to 0
  TCCR3A = 0;

  // Set prescaler to 1
  TCCR3B &amp;= ~(1 &lt;&lt; CS32); //0
  TCCR3B &amp;= ~(1 &lt;&lt; CS31); //0
  TCCR3B |= (1 &lt;&lt; CS30);  //1

  //Reset Timer 3 and set compare value
  TCNT3 = 0;

  // Enable Timer 3 compare interrupt A and B
  TIMSK3 |= (1 &lt;&lt; OCIE3B);
  TIMSK3 |= (1 &lt;&lt; OCIE3A);

  //Enable global interrupts
  sei();

  //Set Refresh Rate
  OCR3A = 1000;
  OCR3B = 100 / 0.0625;
}

void loop() {
  delay(100);
}

ISR(TIMER3_COMPA_vect) {
  PORTD &amp;= ~_BV(pin1); //LOW
  OCR3A = 160;
}

ISR(TIMER3_COMPB_vect) {
  TCNT3 = 0;
  PORTD |= _BV(pin1); //HIGH
}
The problem is here:

ISR(TIMER3_COMPB_vect) {
  TCNT3 = 0;
  ...


If you want to get anything that vaguely looks like accurate timings,
you should never reset the timer. The MCU needs time to process an
interrupt: it has to save the program counter to the stack, load the
address of the interrupt vector, execute it (it's typically a jump),
save all the registers it needs to the stack, and only then can it start
executing the code you wrote in the ISR. From your experiment, it looks
like all this process takes about 1&nbsp;µs. But don't take this delay
for granted: from time to time the interrupt will fire while the MCU is
processing another interrupt, and this will increase the latency.

You have two options:


Update the compare registers in order to program the next interrupts
some time in the future. In this case, the COMPB ISR would do
OCR3A = OCR3B + 160; OCR3B += 1600;. Do not worry about the
overflows: they do the Right Thing.
Let the timer reset itself to zero: it will then do so without
loosing a single cycle. See the CTC and fast PWM modes of the timer.


For your specific use case, PWM seems like the obvious choice. Not only
will the timer handle the resetting itself, it can also generate the
output signal without requiring you to write any ISR. Beware that in
this case the period of the signal is whatever you load in corresponding
compare register plus one, and the duration of the pulse is another
compare register plus one.

As a side note:

  // Reset Timer 3 Control Register to 0
  TCCR3A = 0;


I would also reset TCCR3B. The Arduino core configures both registers
for it's own purposes, so it would be safer to clear them both.