While-Schleife wegoptimiert

Ich habe den folgenden Code in meinem Mikrocontroller-Programm:

// Wait for ADC conversion to complete
while ( ( ADCSRA && _BS( ADSC ) ) == _BS( ADSC ) ) {}

Wobei ADCSRA ein Register ist, das seinen Wert ändert, sobald eine analoge Umwandlung abgeschlossen ist, und wo ich warten möchte, bis ein bisschen klar ist. Dieses Bit zeigt an, dass die Konvertierung abgeschlossen ist.

Betrachtet man den resultierenden Assemblercode, wird die gesamte Schleife durch eine einzige Anweisung ersetzt:

in      r24, 0x06       ; ADCSRA

Das Register wird gelesen, aber sein Wert wird nicht einmal getestet!?

Wie muss ich meinen C++-Code ändern, um den Compiler anzuweisen, das Register immer wieder neu zu überprüfen, ohne das Programm unnötig zu verzögern?

Ich verwende die avr-gcc-Toolchain.

EDIT: Ich habe den Code wie folgt geändert (Thnx: lhballoti):

while ( ( ADCSRA & _BS( ADSC ) ) == _BS( ADSC ) ) {}

Was den Assembler-Code geändert hat zu:

38:   36 99           sbic    0x06, 6         ; 6
3a:   fe cf           rjmp    .-4             ; 0x38 <__CCP__+0x4>

Was scheinbar das Problem löst.

Auf dieser Seite finden Sie das vollständige Programm und den daraus resultierenden zerlegten Code.

Wollen Sie nicht ein bitweises UND verwenden?
Normalerweise würden Sie die Register als flüchtig deklarieren, und dann werden Schleifen, in denen Sie nichts ändern, nicht optimiert ... aber das sollte für Sie in den Include-Dateien erledigt werden.
Obwohl ich den Fehler sofort entdeckt habe, habe ich Probleme zu verstehen, warum der Compiler die Schleife im ersten Fall wegoptimiert hat. Wenn ADCSRAnicht volatil ist, unterliegt nicht auch der zweite Fall der gleichen Optimierung?
Sie sollten Ihre Frage nicht mit der Antwort bearbeiten, sondern die Antwort von jemandem akzeptieren oder Ihre eigene Antwort schreiben und akzeptieren.
@Kellenjb - Jippie hat es hinzugefügt, bevor es eine Antwort war. lhballoti gab es zuerst nur als Kommentar.
@Kellenjb zum Zeitpunkt des Schreibens war es keine Antwort, nur ein Kommentar. Außerdem kann ich in Kommentaren keine Formatierung vornehmen, wodurch der Kommentar sehr schlecht lesbar wird. Deshalb habe ich mich entschieden, die Frage zu aktualisieren.

Antworten (1)

Sie sollten ein bitweises UND verwenden. Der Ausdruck in der ersten whileSchleife wird zu Null ausgewertet, was dazu führt, dass der Compiler die Schleife vollständig entfernt.