Electrical – AVR Timer/Counter Overflow and ISR

atmegaavr

I want to create a PWM on any PIN and therefore using ISRs to achieve this. The setup I chose, working with my ATMEGA328p and Timer0 is:

static inline void initTimer0(void) {
    // Timer Counter Control Register B
    // Must b4 /64 or more for ISR timing
    TCCR0B |= (1 << CS00) | (1 << CS01);

    // Timer Counter Interrupt Mask Register
    // both output compare interrupts
    TIMSK0 |= ((1 << OCIE0A) | (1 << OCIE1B));

    // Timer Counter Overflow Interrupt Enable
    TIMSK0 |= (1 << TOIE0);

    sei();
}

/* Timer/Counter0 Overflow */
// called whenever TCNT0 overflows
ISR(TIMER0_OVF_vect) {
    PORTB |= (1 << 0);
    OCR0A = brightnessA;
}

// ISR fired when a match occurs
ISR(TIMER0_COMPA_vect) {
    PORTB ^= (1 << 0);
}

int main(void)
{
    setup();
    int d = 10;

    while (1) 
    {
        for (int i = 0; i < 255; i++) {
            _delay_ms(d);
            brightnessA = i;
        }


    }
}

I would have expected that the LED on PORTB would dim up but nothing happens. I think I have a gap in understanding here. I would have assumed that TIMER0_COMPA_vect ISR would fire everytime I reach the new OCR0A compare value and turn the LED of, therefore control the duty cycle.

Can you help me?

Thanks

Best Answer

You need to configure the waveform generation mode as well in order to get this working. Page 128 of ATmega328 Datasheet describes exactly how WGM bits need to be set.

19.5. Output Compare Unit

The 8-bit comparator continuously compares TCNT0 with the Output Compare Registers (OCR0A and OCR0B). Whenever TCNT0 equals OCR0A or OCR0B, the comparator signals a match. A match will set the Output Compare Flag (OCF0A or OCF0B) at the next timer clock cycle. If the corresponding interrupt is enabled, the Output Compare Flag generates an Output Compare interrupt. The Output Compare Flag is automatically cleared when the interrupt is executed. Alternatively, the flag can be cleared by software by writing a '1' to its I/O bit location. The Waveform Generator uses the match signal to generate an output according to operating mode set by the WGM02, WGM01, and WGM00 bits and Compare Output mode (COM0x[1:0]) bits. The max and bottom signals are used by the Waveform Generator for handling the special cases of the extreme values in some modes of operation.

This means you need to configure the TCCR0A register as well accordingly.