Timer/Counter0 – 8-bit timer
Timer/Counter1 – 16-bit timer.
Timer/Counter2 – 8-bit timer.
Timer/Counter is useful for:
This will detail Timer/Counter0, but the others are similar.
TCNT0 – Timer/CouNTer 0 (8-bits).
-
Read and write accessible.
A clock is associated with the register.
Each time the clock ticks, TCNT0 is incremented.
When TCNT0 goes from 255 to 0, an overflow flag (TOV0 flag in TIFR) gets set.
OCR0 – Output Compare Register (8-bits).
-
Read and write accessible.
The value in OCR0 is compared with the value in TCNT0.
When OCR0 and TCNT0 are equal, we can trigger other actions, e.g.,
TIMSK – TImer MasK Register.
TIFR – TImer Flag Register.
-
-
FOC0 – Force Ouput Compare, we'll just leave this cleared.
WGM01:0 – Waveform Generation Mode.
COM01:0 – Compare Match Output Mode.
Lookup table to determine pin action.
In order for pin action to occur, PORTB3 must be configured for output.
With WGMM01:0 cleared, the options are:
| COM01 | COM00 | Description |
| 0 | 0 | Normal port operation, OC0 disconnected |
| 0 | 1 | Toggle 0C0 on compare match (TCNT0 = OCR0) |
| 1 | 0 | Clear OC0 on compare match |
| 1 | 1 | Set OC0 on compare match |
| CS02 | CS01 | CS00 | Description |
| 0 | 0 | 0 | No clock source (Timer/Counter stopped) |
| 0 | 0 | 1 | clk |
| 0 | 1 | 0 | clk/8 |
| 0 | 1 | 1 | clk/64 |
| 1 | 0 | 0 | clk/256 |
| 1 | 0 | 1 | clk/1024 |
| 1 | 1 | 0 | External clock source on T0 pin. Clock on falling edge. |
| 1 | 1 | 1 | External clock source on T0 pin. Clock on rising edge. |
.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 0×00 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