# Setting the sampling rate for timer interrupt

I had performance problems with the data acquisition and after some reading on the web, someone told to define a timer with the frequency I need (50hz):

``````// TIMER 1 for interrupt frequency 50 Hz:
cli(); // Stop interrupts.

TCCR1A = 0; // Set entire TCCR1A register to 0.
TCCR1B = 0; // Same for TCCR1B.
TCNT1  = 0; // Initialize counter value to 0.

// Set compare match register for 50 Hz increments.
OCR1A = 39999; // = 16000000 / (8 * 50) - 1 (must be <65536)
// Turn on CTC mode.
TCCR1B |= (1 << WGM12);
// Set CS12, CS11 and CS10 bits for 64 prescaler.
TCCR1B |= (0 << CS12) | (1 << CS11) | (1 << CS10);
// Enable timer compare interrupt.
TIMSK1 |= (1 << OCIE1A);

sei(); // Allow interrupts.
``````

But with that, I was unable to achieve good performance; I was expecting 50 reading / seconds. Luckily, I've changed for 8 bits prescaler instead of 64 and I've start to get better performance:

``````// Set CS12, CS11 and CS10 bits for 8 prescaler.
TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10);
``````

But, honestly, I'm a newbie and I don't understand why!

• This is definitely no newbie-level stuff. If yo have enough patience, study gammon.com.au/timers and you will have all your answers. Jan 25, 2017 at 21:42
• @EdgarBonet thanks for the reference. I see Atmega2560 code. I start from Atmega328 samples to implement timer. Jan 25, 2017 at 21:51
• The Timer 1 of the ATmega2560 and the ATmega328P are essentially identical. You can study either and apply what you learn to the other. Jan 26, 2017 at 8:18

`// = 16000000 / (8 * 50) - 1 (must be <65536)` that `8` in the formula refers to the prescaler. So this formula expect you to have a /8 prescaler. But four lines below you used a /64 prescaler. So your timer runs 6.25 Hz.