9

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.

jippie
  • 33,033
  • 16
  • 93
  • 160
  • 3
    Don't you mean to use a bitwise AND? – lhballoti Jul 07 '12 at 17:15
  • usually you would declare the registers to be volatile, and then loops where _you_ don't modify things won't be optimized... but that should be done for you in the include files. – W5VO Jul 07 '12 at 17:21
  • Although I spotted the mistake right away, I'm having trouble understanding why the compiler optimized the loop away in the first case. If `ADCSRA` isn't volatile, isn't the second case also subject to the same optimization? – lhballoti Jul 07 '12 at 17:57
  • You shouldn't edit your question with the answer, rather accept someones answer or write your own answer and accept it. – Kellenjb Jul 07 '12 at 18:27
  • @Kellenjb - jippie added it before it was an answer. lhballoti first just gave it as a comment. – stevenvh Jul 07 '12 at 18:40
  • @Kellenjb it wasn't an answer at the time of writing, merely a comment. Also I cannot do any formatting in comments, rendering the comment very poor to read. That's why I chose to update the question. – jippie Jul 07 '12 at 18:41

1 Answers1

11

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.

lhballoti
  • 258
  • 4
  • 8