Tengo el siguiente código en mi programa de microcontrolador:
// Wait for ADC conversion to complete
while ( ( ADCSRA && _BS( ADSC ) ) == _BS( ADSC ) ) {}
Donde ADCSRA es un registro que cambiará su valor una vez que se complete una conversión analógica y donde quiera esperar un poco para que quede claro. Este bit indica que la conversión se completó.
Mirando el código de ensamblaje resultante, todo el bucle se reemplaza por una sola instrucción:
in r24, 0x06 ; ADCSRA
¿El registro se lee, pero su valor ni siquiera se prueba?
¿Cómo tengo que cambiar mi código C ++ para indicarle al compilador que vuelva a verificar el registro, sin retrasar innecesariamente el programa?
Yo uso la cadena de herramientas avr-gcc.
EDITAR: cambié el código de la siguiente manera (Thnx: lhballoti):
while ( ( ADCSRA & _BS( ADSC ) ) == _BS( ADSC ) ) {}
Que cambió el código de ensamblaje a:
38: 36 99 sbic 0x06, 6 ; 6
3a: fe cf rjmp .-4 ; 0x38 <__CCP__+0x4>
Lo que aparentemente resuelve el problema.
Consulte esta página para ver el programa completo y su código resultante desmontado.
ADCSRA
no es volátil, ¿el segundo caso tampoco está sujeto a la misma optimización?Respuestas:
Debería estar utilizando un AND bit a bit. La expresión en el primer
while
bucle se evalúa a cero, lo que hace que el compilador elimine el bucle por completo.fuente