# AVR Timer1 OCR1A controls TIMER1_COMPB_vect interrupt!

I was struggling with timer interrupts in my project. I couldn't make it work properly. So I decided writing a simple code and I saw a very interesting case.

ISR(TIMER1_COMPB_vect)
{

PORTB ^= (1 << PORTB5);

}

int main(void)
{
cli();          // disable global interrupts
TCCR1A = 0;     // set entire TCCR1A register to 0
TCCR1B = 0;     // same for TCCR1B

OCR1A = 10000;
OCR1B = 100;

TCCR1B |= (1 << WGM12);

TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);

TIMSK1 |= (1 << OCIE1A);
TIMSK1 |= (1 << OCIE1B);
DDRB= 0xFF;

#define F_CPU 16000000
sei();
while (1)
{

}
}


Here is my code. When I change OCR1B value, nothing happens, but if I change OCR1A value then blinking gets faster. Is there a logical explanation for this?

By setting TCCR1B |= (1 << WGM12); you operate the timer in CTC mode counting from 0 up to the value assigned to OCR1A and back to zero again.

With the given value of OCR1A = 10000; the timer counts 0-10000, 0-10000...
For each 0-10000 count you get a Compare B Match Interrupt when the counter reaches the value of 100 (because you have set OCR1B = 100).

By changing OCR1A you essentially change the upper count limit of the timer which means that you also change the duration of each count cycle, so the Compare B Match Interrupt occurs faster.

As an example, if you set OCR1A = 5000; the Compare B Match Interrupt occurs twice as fast compared to when OCR1A = 10000; because the timer restarts the count when it reaches 5000 instead of 10000 so the counter period shortens.

As a side-note, make sure that you include in your code the interrupt handler functions for all the enabled interrupts (ISR(TIMER1_COMPA_vect) seems to be missing) or resets may occur.

• I forgot to mantion about something. When I change the value of OCR1B the blink speed does not change. I will add it to my question – Zgrkpnr__ May 4 '15 at 18:30
• @Zgrkpnr__ The value of OCR1A controls the period of Timer 1. No matter what the value of OCR1B is, the Compare B Match Interrupt still occurs one time per count cycle with a rate controlled by the period of the timer (OCR1A value) – alexan_e May 4 '15 at 18:37
• @Zgrkpnr__ That is up to you, the timer has several modes and the interrupt functionality may or may not be useful depending on the mode you use. You could create a PWM signal using OCR1A to control the frequency and OCR1B to control the duty cycle but there is not much point in that since timer has better suited PWM modes. – alexan_e May 4 '15 at 18:46
• I edited my comment. As a matter of fact, I did'n understand you at the first place correctly. Now I understand that "B occurs only once in a cycle of 0 to ORC1A no matter what it's value is". – Zgrkpnr__ May 4 '15 at 18:53