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?
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
> 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?
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)
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
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?