Hallo,
ich beschäftige mich gerade mit der PWM-Problematik für ein LED-Projekt.
Ich benutze auf dem Board von Pollin einen Atmega8, der extern mit 16MHz
getaktet wird. Der µC macht auch soweit erstmal das, was er soll.
Programmierung mit AVRISPMKII funktioniert, die UART gibt mir das
Gewünschte auf dem Terminal aus, die Interrupts und die Timer
funktionieren. Soweit so gut.
Für die PWM-Geschichte versuche ich, den erste Codevariante aus dem TUT
zu verwenden:
http://www.mikrocontroller.net/articles/Soft-PWM
Ich möchte mit 100Hz und 255 Schritten arbeiten. Ich lasse also meinen
Timer bis 627 zählen, das sind bei 16MHz 25,5kHz. Wenn ich jetzt mit
dieser Frequenz jeweils bis 255 zähle, dann sind das ca. 100Hz.
Ich habe das nach bestem Wissen und Gewissen programmiert, aber ich muss
einen ganz hohlen Denkfehler gemacht haben, denn die LED wird nicht etwa
dunkler, sondern sie blinkt nur mit ca. 2Hz. Die UART sagt, dass der
PWM-Zähler brav immer von 0 bis 255 zählt und auch an der entsprechenden
Stelle die LED abschaltet. Also z.B. bei 150, wenn der Sollwert bei 150
steht. Aber irgendwie geht das viel zu langsam.
Ich weiß echt nicht, was ich noch machen könnte. Ich habe das TCCR1B
auseinandergenommen, überall die Frequenzen geprüft und bin mit meinem
Latein erstmal am Ende. Es wäre schön, wenn mal jemand über meinen
Quellcode drüber schauen könnte.
Danke!
Olaf
Hallo,
danke für die Antworten!
@Skriptkiddy:
Ich habe jetzt das WGM auf 0100 geändert, damit laut Datenblatt jetzt
das OCR1A für CTC benutzt wird. Leider macht der Timer das gleiche, wie
vorher?!
Was mich am meisten wundert ist, dass ich mit den vorherigen
Einstellungen problemlos die 1s Zeitbasis für eine Uhr realisiert
bekommen habe. Dort habe ich nur noch den 1024 Prescaler dringehabt und
dann bis 15625 gezählt. Das hat wunderbar funkioniert...
@Oger-Berserker:
Danke für den Hinweis. Ich habe das so auseinandergezogen, damit ich
besser nachschauen kann, was die einzelnen Bits bedeuten.
Also da deine UART-Verbindung funktioniert schätze ich mal das deine
Fuses korrekt eingestellt sind. Wenn nicht kannst du dort ja nochmal
genau nachschauen.
@Oger-Berserker:
Ja, die Fuses sind in Ordnung. Extern-Crystal/Resonator, High-f... Ich
werde morgen mal sehen, ob ich an ein Oszi rankomme, evtl. bringt mich
das weiter.
Oger, ich würde das Programm zuerst mal vereinfachen.
1) Weg mit den anderen Interrupts (INT0, INT1)
2) ISR für den COMPA-Interrupt entschlacken.
Die UART-Ausgabe inkl. itoa() haben dort nichts zu suchen. Die
Debugausgabe von pwm_cnt ist wertlos. Wenn du COMPA-Interrupts
verlierst, weil dein Debuggerötel zu lange dauert, wird zwar pwm_cnt
sauber hochgezählt aber die PWM funktioniert nicht mit der
beabsichtigten Frequenz.
Pi*Daumen:
Aufruf des COMPA-IRQ mit 25,5kHz, d.h. alle 0,04 ms.
Reine Debugausgabe von 2 bis 8 Zeichen bei 9600 Baud: 2 bis 8 ms!
=> Statt 25.5 kHz hast du effektiv nur noch 0,5 kHz bis 0,125 kHz
@Helfer:
Ich glaub' es nicht, die UART-Geschichte in der ISR des COMPA war das
ganze Problem! Jetzt funktioniert alles wunderbar. Also daran hätte ich
nie gedacht, dass die Umwandlung für uart_puts und dann natürlich die
megalangsame Ausgabe selber mir meinen PWM-Takt verderben... Die UART
war immer mein Standard-Debugger und weil ich kaum mal etwas wirklich
schnelles gemacht habe, ist es mir nie aufgefallen, was da an Takten
"verloren geht".
Herzlichen Dank für deine Hilfe!
Oger