Schnelles PWM- und Atmega1280-Problem

Hallo, ich habe einige Probleme zu verstehen, wie man einen Timer an einen Pin bindet, und deshalb läuft mein Code nicht...

#include <avr/io.h>

void init_PWM(void)
{
    TCCR0A|=(1<<WGM00)|(1<<WGM01)|(1<<COM0A1)|(1<<CS00);

    //Set OC0 PIN as output. It is  PB3 on ATmega16 ATmega32

    DDRB|=(1<<PB7);
}

void setPWM(uint8_t duty)
{
   OCR0A = duty;
}

void main (void)
{
   uint8_t brightness = 0;
   init_PWM();

   for (brightness=0; brightness<=255; brightness++)
   {
      setPWM(brightness);
      _delay_ms(100);
   }
}

Mein Problem ist, wie man den Timer PB7 zuweist?

Mein Ziel ist eine blinkende LED auf PB7 mit FastPWM-Modus.

Antworten (1)

Ok, ich kann ein paar Probleme mit diesem Code sehen (ich gehe davon aus, dass dies Ihr Datenblatt ist ):

  • Wenn Sie ein sanftes Fading wünschen, verwenden Sie zunächst den 16-Bit-Timer anstelle von 8-Bit (TCCR1A).
  • Sie möchten Fast PWM, haben es jedoch auf Phase Correct eingestellt (Seite 148, Sie möchten Modus 14)
  • Sie geben nicht die gewünschte Frequenz an, im Fast-PWM-Modus müssen Sie laut Datenblatt den TOP-Wert einstellen, dazu müssen Sie eine Berechnung durchführen (Formel auf Seite 152 oben).
  • Sobald Sie Ihre TOP berechnet haben, muss der ICR1 auf diesen Wert eingestellt werden (verwenden Sie einen Prescaler, wenn Ihre Zahl größer als 65535 ist, Tabelle auf Seite 161)
  • Um PWM auf OC0A (PINB7) zu aktivieren, müssen Sie sowohl COM0A1 als auch COM0A0 einstellen

Siehe dieses Beispiel, es ist für den Atmega128 und verwendet einen 16-Bit-Timer. Die Frequenz beträgt 120 Hz und meine CPU-Taktfrequenz beträgt 16 MHz. Daher habe ich mit der Formel ein TOP (16665) erhalten und mein Prescaler war 8, glaube ich.

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

int main(void) {

    //Fast PWM, using inverted mode (default low)
    TCCR1A |= 1<<WGM11 | 1<<COM1A1 | 1<<COM1A0;
    TCCR1B |= 1<<WGM12 | 1<<WGM13 | 1<<CS11;

    //Top
    ICR1 = 16665;

    //Set pins to input/output

    DDRB |= 1<<PINB5;

    OCR1A = 0;

    while(1) {
        //continuous loop where everything happens
        int i;

        for(i=0; OCR1A<ICR1; i+=166) {
            OCR1A = i;
            _delay_ms(6);
        }

        for(i=0; i<ICR1; i+=166) {
            OCR1A = ICR1 - i;
            _delay_ms(6);
        }

        OCR1A = 0;
        _delay_ms(500);

    }

}
+1 Sehr gründliche Antwort. Sie sollten den Teil "(PINB7) Sie müssen sowohl COM0A1 als auch COM0A0 einstellen" fett formatieren, da dies die Hauptfrage war.