Search code examples
widthavrpulseatmega

Pulse width modulation (PWM) on AVR Studio


I'm trying to use PWM for an LED on an ATmega8, any pin of port B. Setting up timers has been a annoying, and I don't know what to do with my OCR1A. Here's my code, and I'd love some feedback.

I'm just trying to figure out how use PWM. I know the concept, and OCR1A is supposed to be the fraction of the whole counter time I want the pulse on.

#define F_CPU 1000000  // 1 MHz

#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>

int main(void){

    TCCR1A |= (1 << CS10) | (1 << CS12) | (1 << CS11);
    OCR1A = 0x0000;
    TCCR1A |= ( 0 << WGM11 ) | ( 1 << WGM10 ) | (WGM12 << 1) | (WGM13 << 0);
    TCCR1A |= ( 1 << COM1A0 ) | ( 0 << COM1A1 );
    TIMSK |= (1 << TOIE1); // Enable timer interrupt
    DDRB = 0xFF;
    sei(); // Enable global interrupts
    PORTB = 0b00000000;

    while(1)
    {
        OCR1A = 0x00FF; //I'm trying to get the timer to alternate being on for 100% of the time,
        _delay_ms(200);
        OCR1A = 0x0066; // Then 50%
        _delay_ms(200);
        OCR1A = 0x0000; // Then 0%
        _delay_ms(200);
    }
}

ISR (TIMER1_COMA_vect)  // timer0 overflow interrupt
{
    PORTB =~ PORTB;
}

Solution

  • You need to initialize your OCR1A with these two lines:

    TCCR1A = (1 << WGM10) | (1 << COM1A1);
    TCCR1B = (1 << CS10) | (1 << WGM12);
    

    And then use this:

    OCR1A = in
    

    And know that the range is 0-255. Count your percentages, and there you have it!

    #define F_CPU 1000000  // 1 MHz
    #include <avr/io.h>
    #include <avr/delay.h>
    #include <avr/interrupt.h>
    
    int main(void){
        TCCR1A = (1 << WGM10) | (1 << COM1A1);
        TCCR1B = (1 << CS10) | (1 << WGM12);
        DDRB = 0xFF;
        sei(); // Enable global interrupts
        PORTB = 0b00000000;
    
        while(1)
        {
            OCR1A = 255;
            _delay_ms(200);
            OCR1A = 125;
            _delay_ms(200);
            OCR1A = 0;
            _delay_ms(200);
        }
    }