I have the following code in my microcontroler program:
// Wait for ADC conversion to complete
while ( ( ADCSRA && _BS( ADSC ) ) == _BS( ADSC ) ) {}
Where ADCSRA is a register that will change its value once an analog conversion is completed and where I want to wait for a bit to be clear. This bit indicates conversion completed.
Looking at the resulting assembly code, the whole loop is replace by a single instruction:
in r24, 0x06 ; ADCSRA
The register is read, but its value isn't even tested!?
How do I have to change my C++ code to instruct the compiler to keep rechecking the register, without unnecessary delaying the program?
I use the avr-gcc toolchain.
EDIT: I changed the code as follows (Thnx: lhballoti):
while ( ( ADCSRA & _BS( ADSC ) ) == _BS( ADSC ) ) {}
Which changed the assembly code to:
38: 36 99 sbic 0x06, 6 ; 6
3a: fe cf rjmp .-4 ; 0x38 <__CCP__+0x4>
Which apperently solves the problem.
Check this page for the complete program and its disassembled resulting code.
1 Answer 1
You should be using a bitwise AND. The expression in the first while
loop evaluates to zero, which causes the compiler to remove the loop altogether.
Explore related questions
See similar questions with these tags.
ADCSRA
isn't volatile, isn't the second case also subject to the same optimization? \$\endgroup\$