Hallo, ich habe gerade ein kleines Problem mit WinAVR. Und zwar habe ich ein Programm (Sourcecode habe ich angehängt), das auf ein Zeichen von der seriellen Schnittstelle wartet und dann INT0 und Timer0 aktiviert. Sobald entweder INT0 ausgelöst wird oder der Timer-Overflow-Interrupt 78mal ausgelöst wurde, werden diese beiden Interrupts deaktiviert und der ADC im Free-Run-Modus (mit Interrupt) aktiviert. Der ADC macht dann 741 Wandlungen und schickt die Daten per RS232 an den PC; dann wird der ADC wieder deaktiviert und das Programm wartet auf das nächste Zeichen von der seriellen Schnittstelle. Das Ganze soll ein kleines digitales Speicheroszilliskop werden: An INT0 hängt ein Komparator für die Triggerung: Der PC, an den das Teil (über einen FT232) angeschlossen ist, sendet ein Startsignal an den AVR. Von da an wartet der AVR auf den Triggerimpuls an INT0. Sobald ein Triggerimpuls kommt - oder wenn nach 80ms immer noch keine Triggerung erfolgt ist (dafür der Timer) - startet der ADC und macht mit 9,259kHz Samplingrate 741 Messungen und schickt die gemessenen Werte zum PC. Am PC wird das dann eben in einem Diagramm dargestellt. Dann schickt das PC-Programm ein neues Startsignal an den AVR und der Zyklus beginnt von neuem. Ok, zurück zum Problem: Der Timer-Overflow-Interrupt inkrementiert eine Variable (im Code ist das timcnt), um nach 78 Timer-Overflow-Interrupts den ADC zu starten. Und diese Variable wird eigentlich beim Start eines neuen Zyklus wieder auf Null gesetzt (Zeile 31 im Code). So, aber wenn ich die Compiler-Optimierung auf O2, O3 oder Os stelle erfolgt diese Wertzuweisung nicht (ich habe mir auch die lss-Datei angesehen; da ist diese Zuweisung auch nicht drin).. Dann läuft die Variable alle paar 10 Messungen über, was reproduzierbar Fehltriggerungen produziert. Schalte ich die Optimierung aber ab oder stelle sie auf O1, klappt alles wie es soll. Ich habe also den starken Verdacht, dass der Compiler die Zuweisung "timcnt = 0" einfach wegoptimiert... Was meint ihr: Ist das ein Bug in avr-gcc/WinAVR? Oder habe ich einfach irgendwas falsch gemacht...
Du hast gerade den zweithäufigsten Fehler gemacht, den man beim Interruptprogrammieren machen kann. Schau dir den Abschnitt über volatile im Artikel Interrupt an.
Helfer schrieb: > Du hast gerade den zweithäufigsten Fehler gemacht, den man beim > Interruptprogrammieren machen kann. Schau dir den Abschnitt über > volatile im Artikel Interrupt an. Vielen Dank, damit geht es. Das Blöde an sowas ist ja: In vielen Fällen funktioniert es auch ohne das volatile problemlos. Ich habe schon einge andere AVR-Programme mit Interrupts und Datenaustausch mit dem Hauptprogramm geschrieben; und da hat auch ohne volatile der Compiler die Wertzuweisungen noch nie wegoptimiert... Naja, wieder was gelernt...
Helfer schrieb: > Du hast gerade den zweithäufigsten Fehler gemacht, den man beim > Interruptprogrammieren machen kann. Schau dir den Abschnitt über > volatile im Artikel Interrupt an. Und der dritthäufigste Fehler: Dem Compiler die Schuld geben. Was täten wir nur ohne die vielen Anfänger, die in den Compilern die ganzen Bugs finden, welche die Profis sonst nie entdeckt hätten...
Markus Frejek schrieb: > Ich habe schon einge andere AVR-Programme mit > Interrupts und Datenaustausch mit dem Hauptprogramm geschrieben; und da > hat auch ohne volatile der Compiler die Wertzuweisungen noch nie > wegoptimiert... Tja, Fehler Nummer vier: Ham'wer schon immmer so gemacht. Nur, weil etwas (anscheinend) funktioniert, ist es noch lange nicht richtig ;) Frühere Versionen des gcc (3.xx) waren bei der Optimierung an dieser Stelle zurückhaltender, da ging das auch ohne volatile. Die aktuellen gcc's nutzen die C-Sprachnorm da gandenloser aus, und dazu gehört eben auch das wegoptimieren von aus Compilersicht sinnlosen Zuweisungen. Und ja, der darf das ;) Oliver
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.