Hallo, ich habe mal eine ganz allgemaine Frage: Es heißt, man sollte die Optimierung im AVRStudio ausschalten, da sonst für die Funktion des Codes benötigte Teile "wegoptimiert" werden. Für eine funktionierende Delay-Funktion soll die Optimierung aber eingeschaltet werden.
>Es heißt, man sollte die Optimierung im AVRStudio ausschalten, da sonst >für die Funktion des Codes benötigte Teile "wegoptimiert" werden. Da werden dann nur Teile wegoptimiert die keine Funktion haben, oder Teile die falsch programmiert wurden (Stichwort: volatile).
Hans schrieb: > Es heißt, man sollte die Optimierung im AVRStudio ausschalten, da sonst > für die Funktion des Codes benötigte Teile "wegoptimiert" werden. Wo "heißt es" denn diesen Quatsch? Wenn der Optimierer benötigten Code entfernt, dann hast du in deinem Code einen Fehler gemacht (z.B. ein volatile vergessen).
Das typische Problem mit selbstgeschriebenen Warteschleifen: void delay(uint16_t time) { for(;time;time--); } Da die Variable time nur lokal geändert werden kann (da ohne volatile), denkt sich der schlaue Compiler, das Ergebnis ist von vornherein klar und freut sich, Zeit zu sparen: void delay(uint16_t time) { time =0; } Deshalb muss die Variable als volatile deklariert sein, um den Compiler zu zwingen, das Ergebnis auszurechen. :-)
Hans schrieb: > ich habe mal eine ganz allgemaine Frage: > > Es heißt, man sollte die Optimierung im AVRStudio ausschalten, da sonst > für die Funktion des Codes benötigte Teile "wegoptimiert" werden. unglücklich ausgedrückt aber es steckt ein Körnchen Wahrheit drinnen. Wenn der Optimizer eingeschaltet ist, dann baut dir der Compiler den Code um. Manchmal ist das ganz schön heftig, so dass im Debugger die Schrittanzeige wild umherspringt, weil der tatsächlich laufende Code mit dem was du geschrieben hast formal nur noch sehr wenig zu tun hat. > Für eine funktionierende Delay-Funktion soll die Optimierung aber > eingeschaltet werden. Nicht 'soll'. Sondern 'muss'! Dein Problem ist jetzt, dass du nicht weißt, was du tun sollst: Optimierer ein oder aus? Nun: Das kommt jetzt drauf an, worauf du in der Simulation aus bist. Willst du die korrekte Funktion kontrollieren, ob Berechnungen stimmen, etc. dann lass den Optimierer ausgeschaltet. Die Zeiten, die dir beim _delay_ms rauskommen werden, werden nicht stimmen. Unter Umständen ist auch das Programm wesentlich größer als es nurmal sein wird. Das soll dich aber insofern nicht berühren, da du ja nur darauf aus bist, das Programm zu verfolgen, was es macht, was es berechnet etc. Das Timing ist an dieser Stelle nicht so wichtig, vor allen Dingen weil es sowieso nicht stimmen wird. Bist du aber darauf aus, dass du im Simulator Timingfragen klärst oder Fehler suchst bei denen Variablen seltsam nicht reagieren oder ungewollt Werte verändern, dann musst du den Optimizer einschalten. Das Programm muss im Simulator exakt so laufen, wie es auch auf dem realen µC laufen wird. Nur dann stimmt der Programmlauf im Simulator in allen Details mit einem Programmlauf auf dem realen µC überein. Und das ist wichtig um derartige Fragen zu klären. Du darfst dich dann natürlich nicht daran stören, dass im Simulator verschiedene Dinge scheinbar anders passieren als du es nieder geschrieben hast. Dein Augenmerk liegt dann nicht mehr auf einer exakten 1:1 Entsprechung zu deinem C-Code, sondern darauf ob der Code aus einer höheren Warte gesehen genau das tut was du willst.
Um genau zu sein, benötige ich die delay-Funktion für mein Display. Dort verwende ich die Standardfunktion aus dem AVRGCC Tutorial http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung , die Wartezeiten sind alle mit delay realisiert. Mein Problem ist nun: Mein Code hängt an genau dieser Programmcode-Stelle, und es liegt an der delay-Funktion. Der bleibt einfach an der hängen:
1 | // 4-bit Modus / 2 Zeilen / 5x7
|
2 | lcd_command( LCD_SET_FUNCTION | |
3 | LCD_FUNCTION_4BIT | |
4 | LCD_FUNCTION_2LINE | |
5 | LCD_FUNCTION_5X7 ); |
In der letzten Zeile in der lcd_command-Funktion steht
1 | _delay_us( LCD_COMMAND_US ); |
Hier bleibt er einfach hängen. Die davorliegenden delay-Funktionen werden gemeistert. Ich habe diese Zeile mal auskommentiert, da klappte der Code dann. Dann wieder eingefügt, dann klappte es auch noch. Heute morgen hängt er wieder an genau dieser Stelle. Gibt es auch eine Möglichkeit, dass es immer funktioniert? Die Optimierung habe ich jetzt aus Os gestellt. Damit hat mein Display gestern auch funktioniert. Irgendwie ist es bei mir Zufall, ob es klappt oder nicht. Und es liegt an der oben beschriebenen Zeile. Nur warum weiß ich nun mal gar nicht.
Hans schrieb: > oder nicht. Und es liegt an der oben beschriebenen Zeile. Nur warum weiß > ich nun mal gar nicht. Du verwechselst höchst wahrscheinlich Ursache und Wirkung. Was du siehst ist, dass hier eine endlose Wartezeit eingelegt wird. Das ist die Wirkung. Die Ursache wird aber höchst wahrscheinlich ganz woanders liegen. Aber wenn du willst, kannst du ja mal den _delay_us( LCD_COMMAND_US ); durch _delay_ms( 1 ); ersetzen.
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.