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.
Sie sollten ein bitweises UND verwenden. Der Ausdruck in der ersten while
Schleife wird zu Null ausgewertet, was dazu führt, dass der Compiler die Schleife vollständig entfernt.
lhballoti
W5VO
lhballoti
ADCSRA
nicht volatil ist, unterliegt nicht auch der zweite Fall der gleichen Optimierung?Kellenjb
stevenvh
Jippie