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?
2 Answers 2
(削除) 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.
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) {}
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.