Necesito tener una pausa programable con la mayor precisión posible. Para lograr esto tengo el siguiente código GCC:
void delay(unsigned char d){
volatile unsigned char i=d;
while(i>0) i--;
}
Que se compila para:
1cc: 89 81 ldd r24, Y+1 ; 0x01
1ce: 81 50 subi r24, 0x01 ; 1
1d0: 89 83 std Y+1, r24 ; 0x01
1d2: 89 81 ldd r24, Y+1 ; 0x01
1d4: 81 11 cpse r24, r1
1d6: fa cf rjmp .-12 ; 0x1cc <__vector_1+0x2c>
(Estoy mostrando solo el código del núcleo del bucle). Esto lleva al hecho de que la precisión es de 7 ciclos, lo cual no es muy aceptable. Sin embargo, veo que el compilador hizo su trabajo no lo más rápido posible: si la variable i
fuera un registro r24, guardaré 3 operaciones y el código sería casi el doble de rápido.
Entonces, ¿cómo puedo decirle al compilador que quiero que esta variable esté en un registro?
PS. Consideraría hacer una pausa con el número programable en nop
's. Pero no puedo imaginar cómo se puede lograr esto. AVR no tiene instrucciones para derivar a la dirección calculada. Por lo que sé, no se puede acceder directamente a la pila en el AVR (si pudiera enviar el valor necesario a la pila y ejecutar la instrucción ret
para saltar a la dirección del programa necesaria, también es un trabajo difícil, pero al menos sería considerable).
ACTUALIZACIÓN Después de cambiar la palabra clave de volatile
a register
(como se describe en una de las respuestas), tengo el siguiente código:
14e: 81 50 subi r24, 0x01 ; 1
150: f1 f7 brne .-4 ; 0x14e <__vector_6+0x1c>
Así que reduje el ciclo de 7 a 2 ciclos. Lo cual es mucho mejor de lo que podía esperar.