Go Down

Topic: Handling timer overflow and compare interrupts in ATMega328 (Read 1 time) previous topic - next topic


When using the arduino software you cannot rely on the control registers to have their default values as indicated in the datasheet! Make sure every bit is set to what you need it to be.
• Upload doesn't work? Do a loop-back test.
• There's absolutely NO excuse for not having an ISP!
• Your AVR needs a brain surgery? Use the online FUSE calculator.
My projects: RGB LED matrix, RGB LED ring, various ATtiny gadgets...
• Microsoft is not the answer. It is the question, and the answer is NO!


I read the AVR Timer app notes and still can't find the clue. Any advices are muchly appreciated.
I wish I have an oscilloscope at hand to check signals.


I usually find that I need to read the sections of the data sheet a few times before I understand it.

This isn't what you are doing, but it may be a good starting point.  The order you do things sometimes make a big difference:  I noticed that you initiate the timer interrupt before setting it up properly (TIMSK2).

This is working code that uses timer 2, and interrupts every 10 microseconds.  Try starting with this and then modifying it to what you want:

Code: [Select]

void SetupTimerISR() {
  // Disable interrupts while setting registers

  // Reset control registers
  TCCR2A = 0;
  TCCR2B = 0;

  // Clear Timer on Compare Match (CTC) Mode
  TCCR2A |= (1 << WGM21);

  // Prescaler x1
  TCCR2B |= (1 << CS20);

  // Interrupt every 160/16e6 = 10 usec
  OCR2A = 159;

  // Use system clock for Timer/Counter2
  ASSR &= ~(1 << AS2);

  // Reset Timer/Counter2 Interrupt Mask Register
  TIMSK2 = 0;

  // Enable Output Compare Match A Interrupt
  TIMSK2 |= (1 << OCIE2A);

  // Enable interrupts once registers have been update

// This ISR is run when Timer/Counter2 reaches OCR2A

Every 10 microseconds, a global variable increments.

Go Up