Forum: Mikrocontroller und Digitale Elektronik delay und Optimierung im AVR Studio


von Hans (Gast)


Lesenswert?

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.

von holger (Gast)


Lesenswert?

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

von Stefan E. (sternst)


Lesenswert?

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

von Floh (Gast)


Lesenswert?

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. :-)

von Karl H. (kbuchegg)


Lesenswert?

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.

von Hans (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.