2

I can use the CTC waveform generation mode to loop to OCRnA and trigger the corresponding TIMER1_COMPA_vect interrupt.

// CTC mode
TCCR1A &= ~(1 << WGM10);
TCCR1A &= ~(1 << WGM11);
TCCR1B |= (1 << WGM12);
TCCR1B &= ~(1 << WGM13);    
TIMSK1 |= (1 << OCIE1A);   
OCR1A = 250;

ISR(TIMER1_COMPA_vect) {}

But if I use CTC mode with ICRn as "TOP" is there a corresponding interrupt vector?

TCCR1A &= ~(1 << WGM10);
TCCR1A &= ~(1 << WGM11);
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << WGM13);    
TIMSK1 |= (1 << ???);    // which interrupt to enable?
ICR1 = 250;

ISR(???) {}              // which interrupt vector?
  • I think it was TIMER1_CAPT_vect. Have to check when I get home. – Gerben May 31 '17 at 8:22
  • It seems I used TIMSK1 |= _BV(ICIE1); ISR(TIMER1_CAPT_vect), but looking at the datasheet, that's not supposed to work. It works, but it's not specified behavior. – Gerben May 31 '17 at 15:34
  • @Gerben That works for me too. Can you elaborate on "not specified behaviour"? The datasheet isn't very explicit as far as I can tell. – 101 May 31 '17 at 23:35
  • @Gerben: This behavior is actually specified. It would seem we had both misread the datasheet. :-/ – Edgar Bonet Jun 1 '17 at 9:04
  • 1
    You are right; I stand corrected. Apparently past me is smarter that present me :-) – Gerben Jun 1 '17 at 9:22
4

No, there isn't. But you do have a simple alternative: use WGM 14 (fast PWM with TOP = ICR1). Then the TOV1 flag will be set after the timer reaches TOP:

TIMSK1 |= (1 << TOIE1);  // enable Timer 1 overflow interrupt

ISR(TIMER1_OVF_vect) {}  // Timer 1 overflow vector

Note that this waveform generation mode behaves very much like the CTC mode. If you do not set any of the COM1 bits in TCCR1A, then there will be no PWM output.


Edit: My bad. As noted by Gerben and confirmed by you, the TIMER1_CAPT_vect can be used, and it is specified in the datasheet, although maybe not very prominently:

In section 17.9.2 “Clear Timer on Compare Match (CTC) Mode”:

An interrupt can be generated at each time the counter value reaches the TOP value by either using the OCFnA or ICFn Flag according to the register used to define the TOP value.

In section 17.11.40 “TIFR5 – Timer/Counter5 Interrupt Flag Register”, in the description of bit 5 (Input Capture Flag):

When the Input Capture Register (ICRn) is set by the WGMn3:0 to be used as the TOP value, the ICFn Flag is set when the counter reaches the TOP value.

2

It does actually seem to work with CTC mode and ICRn as TOP, by using the TIMER1_CAPT_vect interrupt.

// CTC mode with ICRn as TOP
TCCR1A &= ~(1 << WGM10);
TCCR1A &= ~(1 << WGM11);
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << WGM13);

// enable interrupt
TIMSK1 |= (1 << ICIE1);

// TOP value
ICR1 = 100;

// interrupt at TOP
ISR(TIMER1_CAPT_vect) {}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.