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 Konvertierung abgeschlossen ist, und wo ich warten möchte, bis ein bisschen klar ist. Dieses Bit zeigt an, dass die Konvertierung abgeschlossen ist.
Wenn Sie sich den resultierenden Assemblycode ansehen, wird die gesamte Schleife durch eine einzelne 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 weiter zu überprüfen, ohne das Programm unnötig zu verzögern?
Ich benutze 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 in:
38: 36 99 sbic 0x06, 6 ; 6
3a: fe cf rjmp .-4 ; 0x38 <__CCP__+0x4>
Was das Problem anscheinend löst.
Auf dieser Seite finden Sie das vollständige Programm und den daraus resultierenden zerlegten Code.
ADCSRA
es nicht volatil ist, unterliegt nicht auch der zweite Fall der gleichen Optimierung?Antworten:
Sie sollten ein bitweises UND verwenden. Der Ausdruck in der ersten
while
Schleife wird mit Null ausgewertet, wodurch der Compiler die Schleife vollständig entfernt.quelle