Not able to change timer output compare registers in main loop


I am getting pretty frustrated with this issue as I’ve tried all sorts of stuff already but simply can’t find the cause. This code is part of a bigger code, but I’ve posted the simplified (isolated) version since the problem is equally present in it.
I am basically generating a PWM output on pin 10 using timer2’s OCR2A and OCR2B registers which trigger two ISR’s (yes there is a reason to generate the PWM this way…).
The PWM frequency is exactly 1kHz and I want to control the duty cycle by changing OCR2A from within the main loop. However, after writing a new value to OCR2A nothing changes, the PWM stays the same and so does the value in OCR2A. What am I missing here? I’ve even tried to completely re-initialize the timer in the main loop but that doesn’t help either and I don’t see a reason for it to be necessary anyway. The initial set-up in void setup() works just like it should, no issues there. The ADC settings I set are unrelated.

const int pilotOUT = 10;
volatile int duty = 100;

void setup() {
  // put your setup code here, to run once:
  pinMode(pilotOUT, OUTPUT);
  digitalWrite(pilotOUT, LOW);

  cli();  //disable interrupts
    // ADC prescaler
  ADCSRA &= ~(bit (ADPS0) | bit (ADPS1) | bit (ADPS2)); // clear prescaler bits
  ADCSRA |= bit (ADPS1) | bit (ADPS2);                 //  64 

  // Timer2
  // Set the Timer Mode to CTC
  TCCR2A |= (1 << WGM21);

  OCR2A = 100;  //"duty"
  OCR2B = 250;  //"freq"
  TIMSK2 |= (1 << OCIE2A);  //Set the ISR COMPA vect
  TIMSK2 |= (1 << OCIE2B);  //Set the ISR COMPB vect

  TCCR2B |= (1 << CS22);  // set prescaler to 64 and start the timer
  sei();  //enable interrupts

void loop() {
    OCR2A = 200;

ISR (TIMER2_COMPA_vect)  // timer0 overflow interrupt
  PORTB |= (1 << 2);

ISR (TIMER2_COMPB_vect)  // timer0 overflow interrupt
  TCNT2 = 0;
  PORTB &= ~(1 << 2);

I suspect that you have not actually put it into CTC mode. The timers are initialized for pwm mode by init() which runs before setup, to prepare them for using with analogWrite().

Your code makes assumptions about the initial values of these registers which thus are not valid. Figure out what you want all bits in tccr2a/tccr2b set to, and set that with = instead of just setting one bit with |= and hpoing the rest of it is set to what you think.

I agree with Dr. Azzy, and think you are actually in fast pwm to 255 (mode3) as bit 0 is set by the presets.

If you actually get to CTC to OCR2A mode you will not see OCR2B values above OCR2A. You need to rethink you turn on and turn off compare match interrupts.