Wrong Timer1 output Frequency on ATMega32U4

Hello All,

I'm working with the MT-DB-U4 breakout board which uses the ATMega32U4 (16 MHz clock) with Arduino (CDC) bootloader installed. I was working on creating a simple Timer1 Library for use with the microcontroller when I noticed some strange behavior with Timer 1. I later isolated the problem to the code below:

void setup()
{
  DDRC |= (bit(7) | bit(6));
  TCCR1B = (1 << WGM12) | (1 << CS11);  // Configure timer 1 for CTC mode w. clk/8 prescaler
  OCR1A = 10000;                        // Set timer value for 5ms interrupts

  TIMSK1 |= (1 << OCIE1A);              // Output Compare A Match Interrupt Enable
  sei();                                // enable interrupts
}

void loop()
{
   // Do Nothing
}

ISR(TIMER1_COMPA_vect)
{
  PORTC ^= (bit(7) | bit(6));
}

This code is supposed to fire the interrupt every 5 ms (which results in a pin toggle frequency of 100 Hz). However, when I run the code and observe the output, the actual toggle frequency is 3.908 kHz. I also noticed that if I chance the value of OCR1A that the output frequency isn't affected. But if I change the prescalar value, the output changes accordingly. My Goal is to have the timer running in CTC mode so that I can have it periodically fire the interrupt. Can anyone spot anything wrong with this code?

Thanks!
Jason O

Hi everyone,

I ended up solving the problrm. Apparently, you need to explicitly set TCCR1A = 0 or it won't work (I wrongly assumed that it was already cleared on startup). Here's the corrected code.

void setup()
{
  DDRC |= (bit(7) | bit(6));
  TCCR1A = 0;
  TCCR1B = (1 << WGM12) | (1 << CS11);  // Configure timer 1 for CTC mode w. clk/8 prescaler
  OCR1A = 10000;                        // Set timer value for 5ms interrupts

  TIMSK1 |= (1 << OCIE1A);              // Output Compare A Match Interrupt Enable
  sei();                                // enable interrupts
}

void loop()
{
   // Do Nothing
}

ISR(TIMER1_COMPA_vect)
{
  PORTC ^= (bit(7) | bit(6));
}
  • Jason O