Skip to main content
4 of 7
deleted 257 characters in body
bigjosh
  • 10.2k
  • 34
  • 53

Try using a value of 15999 for TOP in OCR1.

You do not need to account for the time it takes to execute the ISR. The timer is free running. In CTC mode, it starts at 0 and counts up to the TOP value, then clears back to zero and starts over again. It can optionally generate an interrupt each time it clears, but this is a side effect - it will count like this completely on its own with or without an interrupt.

The timer continues counting while your ISR executes. Your ISR will get called again the next time the clear happens regardless of how long it takes to execute, as long as it is finished executing before the next clear and the next interrupt.

Therefore, you can also eliminate the lines...

LDI    WR1, BYTE1(988)  ; 12 clock cycles are passed
LDI    WR2, BYTE2(988)  ; We want to wait 1000 ms
LDI    WR3, BYTE3(988)

...since they have no effect.

Note that with the above code, your LED will not toggle exactly every 2 seconds because of jitter due to the fact that the foreground task can be interrupted at random times by the ISR. If it gets interrupted after the compare happens, the LED will not toggle until the next pass. You will still have a very solid 0.5Hz output frequency, there will just be a few dozen cycles of jitter on any given transition. If you want exactly the output to be jitter free +/- 1 cycle, you can enable one of the output compare pins to toggle mode and let the hardware blink the LED for you.

Make sense?

Otherwise, the code looks very nice!

bigjosh
  • 10.2k
  • 34
  • 53