www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega 168 Hardware-PWM


Autor: Marcel Holle (multiholle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe nach einer Anleitung im Netz versucht Hardware-PWM auf meinem 
Atmega 168 zu implementieren. Im groben funktioniert es auch, es tritt 
nur folgendes Problem auf:

Bei "OCR0A = 0" ist die LED nicht aus, sondern leuchtet trotzdem sehr 
schwach. Was mache ich falsch?
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>

uint16_t pwmtable[32] PROGMEM = {0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11, 13,
    16, 19, 23, 27, 32, 38, 45, 54, 64, 76, 91, 108, 128, 152, 181, 215, 255};

int main(void) {
  DDRD = 1 << PD6;
  
  OCR0A = 0;  
  
  TCCR0A = 1 << COM0A1 | 1 << WGM01 | 1 << WGM00;
  TCCR0B = 1 << CS02;
  
  while (1) {
    uint16_t i;
    for (i = 0; i < 32; i++) {
      OCR0A = pgm_read_word(pwmtable + i);
      _delay_ms(200);
    }
  }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marcel Holle schrieb:

> # Bei "OCR0A = 0" ist die LED nicht aus, sondern leuchtet trotzdem sehr
> schwach.

Yep.
Das ist normal.

Die Hardware PWM funktioniert so, dass bei einem Timerwert von 0 auf 
jeden Fall der Ausgang ein geschaltet wird. Danach kommt der Compare 
Match bei 0 und schaltet gleich wieder aus. Aber eine gewisse kurze Zeit 
ist eingeschaltet.

>
> # Wenn ich die pwmtable einmal vernünftig durchlaufen haben, fängt die
> LED ab dem 2. Durchlauf an wilkürlich zu blinken.
>
> Was mache ich falsch?

> uint16_t pwmtable[32] PROGMEM = {0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10,
> 11, 13,
>     16, 19, 23, 27, 32, 38, 45, 54, 64, 76, 91, 108, 128, 152, 181, 215,
> 255};
>

    for (i = 0; i < 256; i++) {
>       OCR0A = pgm_read_word(pwmtable + i);

Oha.
Dein Array ist 32 Einträge groß und nicht 256

Autor: Marcel Holle (multiholle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Dein Array ist 32 Einträge groß und nicht 256
Das habe ich selber auch gerade gemerkt. ^^

> Die Hardware PWM funktioniert so, dass bei einem Timerwert von 0 auf
> jeden Fall der Ausgang ein geschaltet wird. Danach kommt der Compare
> Match bei 0 und schaltet gleich wieder aus. Aber eine gewisse kurze Zeit
> ist eingeschaltet.
Das heißt, ich schreibe eine Funktion "set_pwm(unit16_t value)", welche 
bei "value == 0" den timer deaktiviert und ansonsten den Wert des 
Registers ändert? Oder geht es eleganter?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marcel Holle schrieb:
>> Dein Array ist 32 Einträge groß und nicht 256
> Das habe ich selber auch gerade gemerkt. ^^
>
>> Die Hardware PWM funktioniert so, dass bei einem Timerwert von 0 auf
>> jeden Fall der Ausgang ein geschaltet wird. Danach kommt der Compare
>> Match bei 0 und schaltet gleich wieder aus. Aber eine gewisse kurze Zeit
>> ist eingeschaltet.
> Das heißt, ich schreibe eine Funktion "set_pwm(unit16_t value)", welche
> bei "value == 0" den timer deaktiviert und ansonsten den Wert des
> Registers ändert? Oder geht es eleganter?

Es reicht, wenn du den Ausgansgpin vom Timer wegkoppelst (COM0A1 wieder 
löschen) und den Pin auf 0 setzt.
den Timer kannst du ja weiter laufen lassen.

(Und natürlich umgekehrt, wenn dann wieder ein PWM Wert ungleich 0 
kommt)

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Bei "OCR0A = 0" ist die LED nicht aus, sondern leuchtet trotzdem sehr
>schwach. Was mache ich falsch?

Eigentlich nichts. Aber die PWM erzeugt kurze Spikes. Also entweder bei 
OCR0A = 0 die PWM abschalten oder invertierte PWM benutzen.

MfG Spess

Autor: Marcel Holle (multiholle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, das bekomme ich hin. Wenn 3 PWM-Kanäle brauche, kann ich maximal 
eine Auflösung von 8 Bit verwenden, da nur Timer 1 eine Auflösung von 10 
Bit verwendet. Oder gibt es noch eine andere Möglichkeit auf 10 Bit zu 
kommen?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.