.def temp = r16
ldi temp, 1<<CS02 | 1<<CS00
out TCCR0, temp
ldi temp, 0x00
out TCNT0, temp
ldi temp, 1<<TOV0
out TIFR, temp
; ...
.equ CS00 = 0
.equ CS01 = 1
.equ CS02 = 2
; ...
-
The increment frequency for TCNT0 is: 8×106 cycles/sec / 1024 = 7812Hz
The increment interval is 1/7812 = 128×10-6 sec
The overflow interval is: 128×10-6 sec/clk x 256 clk = 32.768 ms.
If we wanted a 10ms delay, we would need 10ms/128×10-6 = 78 clocks. Instead of writing 0x00 into TCNT0, we would give it 177 (=255-78).
; Function that provides a 10ms delay routine
delay10ms:
.def temp = r16
push temp
ldi temp, 0xff-78
out TCNT0, temp
ldi temp, 1<<CS02|1<<CS00
out TCCR0, temp
in temp, TIFR ; See alternate approach above
ori temp, 1<<TOV0
out TIFR, temp
d10Poll:
in temp, TIFR ; Cannot do sbrs on TIFR
sbrs temp, TOV0
rjmp d10Poll
pop temp
ret
.include "m32def.inc"
.def temp = r16
.org 0x00
rjmp initStack
.org OVF0addr
rjmp ovr0ISR
.org 0x2a
initStack:
start:
rcall initTimer0
sei ; Enable global interrupts
; Initialize timer/counter0 to interrupt every 10ms.
initTimer0:
push temp
ldi temp, 0xff-78 ; make overflow occur in 78 clk ticks.
out TCNT0, temp
ldi temp, 1<<CS02|1<<CS00
out TCCR0, temp
in temp, TIFR
sbr temp, 1<<TOV0 ; Could have use ori
out TIFR, temp
in temp, TIMSK
ori temp, 1<<TOIE0 ; Enables timer/counter0 interrupt
out TIMSK, temp
pop temp
ret
; ISR for timer/counter0 interrupt
; Schedules next interrupt to happen 10ms from now.
ovr0ISR:
push temp
in temp, SREG
push temp
ldi temp, 0xff-78 ; make overflow occur in 78 clk ticks.
out TCNT0, temp
pop temp
out SREG, temp
pop temp
reti