To get this out of the way first: I have already looked at "Timer2 does not work as it should" and "Timer2 “Clear OC2B on Compare Match” not working as expected in CTC mode" but have not found the answers there very useful.
Now on to my problem:
I'm trying to use the Timer2 in CTC mode to have an interrupt every 500us. For this, I have the following code:
#include "TimerTwo.h"
TimerTwo Timer2;
ISR(TIMER2_COMPA_vect) { //ISR on Compare Match A
Timer2.isrCallback();
}
void TimerTwo::initialize() {
cli();
TCCR2A = 0;// set entire TCCR2A register to 0
TCCR2B = 0;// same for TCCR2B
TCNT2 = 0;//initialize counter value to 0
// set compare match register for 2khz increments
OCR2A = 124;// = (16*10^6) / (2000*64) - 1 (must be <256)
// turn on CTC mode
TCCR2A |= _BV(WGM21);
// Set CS22 bit for 64 prescaler
TCCR2B |= _BV(CS22);
// enable timer compare interrupt
TIMSK2 |= _BV(OCIE2A);
sei();
}
void TimerTwo::attachInterrupt(void (*isr)()) {
TIMSK2 |= _BV(OCIE2A);
isrCallback = isr;
}
void TimerTwo::detachInterrupt() {
TIMSK2 &= ~_BV(OCIE2A);
isrCallback = nullptr;
}
and
#ifndef TIMERTWO_H
#define TIMERTWO_H
#include <Arduino.h>
class TimerTwo
{
public: //methods
void initialize();
void attachInterrupt(void (*isr)());
void detachInterrupt();
void (*isrCallback)();
};
extern TimerTwo Timer2;
#endif
It was inspired by the TimerOne library.
However, when I measure the period at the output pin (which I have attached inside some other code) I only get a period of 1ms. Even if I set ORC2A
to 63, this fact doesn't change.
I have the constructor of this called inside my setup()
so the registers should not be overwritten by the wiring.c.
I have also looked at the datasheet of the ATmega328p and checked that all registers are set correctly.
Thanks in advance for your help. If you need any further information, let me know.
isrCallback
after theinitialize
? You should enable timer compare A interrupt in theattachInterrupt
method only. And in theattachInterrupt
it should be set first, than enabled.attachIntterupt
it still does not work.