Hi zusammen, ich hab hier ein kniffliges Phänomen, und (nach langem Suchen) glaube ich die Ursache gefunden zu haben. ich hätte gerne eure bestätigung, und eine idee was ich dagegen tun kann. Gegeben ist eine "Halb-Soft-PWM" auf zwei Pins mit Timer2: Dieser läuft mit Prescaler 8 (bei 16 MHz CPU-Takt also mit 2 MHz), es sind zwei Output-Compares drinnen und der "normale" Overflow-Handler bei 255 (also kein CTC und auch kein implizites Schalten der Ausgänge) In der ISR(TIMER2_OVF_vect) werden beide Pins auf High gesetzt; in den ISR(TIMER2_COMP[A|B]_vect) wird der entsprechende Pin wieder auf low gezogen. Über die OCR(A,B) wird die PWM-Pulsweite gesteuert. Die ISRs sind "as sinmple as possible", bestehen im Wesentlichen nur aus einem sbi/cbi. Soweit, so gut, funktioniert prächtig. Nun ist auch noch Timer0 dazugekommen, ebenfalls mit Prescaler 8, der overflow-handler ist etwas komplexer (aber vergleichsweise auch noch sehr einfach) aber der wird schon eine handvoll Takte verbraten. Arbeite ich nun mit sehr kleinen PWM-Werten (1..3) so passiert es nachvollziehbar, dass sich das PWM-Signal "umdreht", ich also kontinuierlichen High-Pegel mit ganz kurzen Spitzen nach low kriege. Sobald ich den PWM-Wert in den OCR(a,B) erhöhe, normalisiert sich das Bild wieder. So, nun mein Verdacht: Der Interrupt-Handler für Timer0 wird abgearbeitet, und genau während dieser zeit laufen sowohl der Overflow- als auch (wenige Takte später) der Output-Compare-interrupt auf. beide interrupts-Handler werden momentan nicht aufgerufen, da ja grad ein anderer handler läuft, und interrupts global deaktiviert sind. Aber die Interrupts werden "gespeichert" und nachdem der Timer0-handler fertig ist, in der Reihenfolge ihrer Priorität nach aufgerufen. Nun hat der Compare-Match-Vektor eine höhere Priorität als der Overflow-handler, die handler werden also in der genau verkehrten Reihenfolge aufgerufen... Frage: ist meine Erklärung schlüssig? Wenn ja, was tun? ich sehe folgende Möglichkeiten: - per Preload der Timer-Values diese so setzen, dass sie möglichst "entfernt" voneinander ablaufen (ich hätte mal 192 genommen, da ich nie mit so hohen PWM-Werten arbeiten werde) - Im Interrupt-Handler vom Timer0 ander interrupts zulassen (dangaruuuhs) Sonstige ideen? lg Michi
Ich würde im Timer0 Interrupt andere Interrupts zulassen.
>Nun ist auch noch Timer0 dazugekommen, ebenfalls mit Prescaler 8, der >overflow-handler ist etwas komplexer (aber vergleichsweise auch noch >sehr einfach) aber der wird schon eine handvoll Takte verbraten. Wenn sie eh Zeitgleich überlaufen, kannst du nicht den Overflow-Handler von Timer 0 in die ISR des Timer 2 packen. Gruß Matthias
Michael Reinelt schrieb: > Frage: ist meine Erklärung schlüssig? Wenn Du Timer0 deaktivierst und dann das Problem nicht mehr auftritt, klingt das nach ner plausiblen Erklärung. > Sonstige ideen? Du könntest im Compare-Match-Vektor abfragen, ob das Interrupt-Flag für den Overflow gesetzt ist. Damit kannst Du den Fall erkennen. Wenn es nicht so wichtig ist den Zyklus exakt einzuhalten, könntest Du dann diesen einen Zyklus ausfallen lassen und z.B. den nächsten dann doppelt so lang machen.
Gerd E. schrieb: > Du könntest im Compare-Match-Vektor abfragen, ob das Interrupt-Flag für > den Overflow gesetzt ist. Damit kannst Du den Fall erkennen. Ha! Wusst ichs doch dass es eine simple und effektive lösung gibt! Danke vielmals!
Stone schrieb: >>Nun ist auch noch Timer0 dazugekommen, ebenfalls mit Prescaler 8, der >>overflow-handler ist etwas komplexer (aber vergleichsweise auch noch >>sehr einfach) aber der wird schon eine handvoll Takte verbraten. > > Wenn sie eh Zeitgleich überlaufen, kannst du nicht den Overflow-Handler > von Timer 0 in die ISR des Timer 2 packen. > > > Gruß Matthias Mittlerweile weiss ich dass sie nicht zeitgleich laufen werden, da Timer 0 ein CTC benötigen wird. Damit scheidet auch meine "Preload" Variante aus. Aber der Vorschlag von robberknight zusammen mit dem zulassen von interrupts im timer0-handler wird das problem wohl aus der Welt schaffen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.