He estado intentando parpadear un LED con el ensamblaje de AVR. Estoy usando un chip ATMega168 y una cadena de herramientas avr-gcc. Aquí está mi código:
.include "m168.h"
.global main
main:
ldi r16, 0b00000001
out DDRB,r16 ; Set PB0 to output
out PORTB,r16 ; Set PB0 high
ldi r16, 0b00000101
out TCCR0B,r16 ; Set prescaler to 1024
loop:
in r17, TCNT0 ; If the counter is >= 128,
cpi r17, 128 ; branch to dim
brge dim ; otherwise continue to light
light:
sbi PORTB, 0
rjmp loop
dim:
cbi PORTB,0
rjmp loop
Me imagino que mi LED debería estar encendido ~ 50% del tiempo (valores 0-127) y apagado el 50% del tiempo (valores 128-255). Pero no se ilumina (visiblemente).
Si ejecuto el programa, aunque mi cabeza sea así.
- El contador TCNT0 comienza en cero
- el LED está encendido
-
loop
se ejecuta sin bifurcar hastadim
-
light
salta de nuevo aloop
Los pasos 3 y 4 ocurren en un bucle para todas las ventas de TCNT0 donde 0 < = TCNT0 < = 127, lo que significa que la luz está encendida todo este tiempo
- TCCR0B llega a 128, por lo que las ramas se atenúan
-
dim
salta de nuevo aloop
Los pasos 5 y 5 suceden en un bucle para todas las ventas de TCNT0 donde 128 < = TCNT0 < = 255, lo que significa que la luz está apagada todo este tiempo
- Eventualmente, TCNT0 se desborda y volvemos a encender el LED. Y así sucesivamente ...
Suponiendo que mi velocidad de reloj es de 8Mhz (no sé cómo encontrar esto en la hoja de datos), el temporizador se incrementa una vez cada 1024 ciclos de reloj o aproximadamente 4 ms (10248 (1/8 ^ 6)). Lo que significa que mi LED debería estar encendido durante 512 ms (128 * 4) y luego apagado durante 512 ms.
Claramente, me estoy equivocando de algo aquí o la lógica anterior no es sólida, pero no estoy segura de dónde.
Editar:
Si configuro la comparación para comparar con 255, parpadeará. ¡Esto me confunde aún más!