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!
-
1This is definitely no newbie-level stuff. If yo have enough patience, study gammon.com.au/timers and you will have all your answers.Edgar Bonet– Edgar Bonet01/25/2017 21:42:47Commented Jan 25, 2017 at 21:42
-
@EdgarBonet thanks for the reference. I see Atmega2560 code. I start from Atmega328 samples to implement timer.Jonathan Anctil– Jonathan Anctil01/25/2017 21:51:40Commented Jan 25, 2017 at 21:51
-
1The Timer 1 of the ATmega2560 and the ATmega328P are essentially identical. You can study either and apply what you learn to the other.Edgar Bonet– Edgar Bonet01/26/2017 08:18:24Commented Jan 26, 2017 at 8:18
1 Answer 1
// = 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.
When you changed it to /8, you got the correct frequency.