Timer Interrupts in C: CS02 CS01 CS00
Timer Interrupts in C: CS02 CS01 CS00
We are originally interested in using Timer/Counter0 and the rest of this handout will
refer to Timer/Counter0.
All interrupts are individually masked with the Timer Interrupt Mask register (TIMSK).
The Timer/Counter can be clocked internally, via the prescaler, or by an external clock
source on the T0 pin. The clock source can be selected in the STK500 ISP (In System
Programming) window by selecting Fuses and then the required source. For this
particular practical I would suggest:
This gives a clock rate of 1MHz which means that each clock pulse period is 1us. (i)
There are two ways to determine the count value one is to use an 8-bit comparator
which continuously compares TCNT0 with the Output Compare Register (OCR0).
Whenever TCNT0 equals OCR0, the comparator signals a match and generates an
interrupt. The other, and the method we will use, is to allow the value stored in TCCR0 to
count up to 255 and then reset to zero this will generate a timer overflow interrupt
(TOIE0).
To program this timer we need to program TCCR0. As far as we are concerned all we
need to worry about are the 3 least significant bits, which set a prescalar. The prescalar
divides the clock by 8, 64, 256 or 1024 depending upon the values entered.
TCCR0
FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
Address 0x33
The values for TCCR0 can be determined from Table 1.
1
0 0 0 No clock source (Timer/Counter stopped).
0 0 1 clkI/O/(No prescaling)
0 1 0 clkI/O/8 (From prescaler)
0 1 1 clkI/O/64 (From prescaler)
1 0 0 clkI/O/256 (From prescaler)
1 0 1 clkI/O/1024 (From prescaler)
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.
Table 1
As far as the count is concerned, we just need to enter the value into TCNT0. However
we need to calculate the numbers based upon the required delay.
Example
We require a delay of 250ms. This means that the timer will generate an interrupt every
second.
Answer
Given that each clock pulse period is 1 x 10-6 seconds (1us which was stated in (i))
or
As the timer counts up then we need to load TCCR0 with 255 -244 = 11 or in
hex (0x0b).
The other register we need to program is the timer mask register (TIMSK).
2
The only other thing that is required before the interrupt will work is to enable the Global
interrupts using the sei instruction. Alternatively we could have selected bit 7 in the
SREG (address 0x3f)
I T H S V N Z C
SREG
Address 0x3F
This can also be enabled using sei()
Page 4 shows a C program using the timer to flash the leds on and off at about 1 second
intervals.
Note the line SIGNAL(SIG_OVERFLOW0) will
load
the
vector
table
with
the
correct
address
of
the
interrupt
handler.
The
^
sign
is
an
exculsive
OR.
XOR
Truth
table
Inputs
Output
0
0
0
0
1
1
1
0
1
1
1
0
Hence toggle = toggle ^ 0xff; will cause the LEDs to all change value (from
0s to 1s and vice versa), on each pass.
The comments should therefore make the rest of the program on page 4 understandable.
3
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
void init(void)
{
DDRA = 0xff;
TCNT0 = 0x00;//Count = 0
TCCR0 = 0x05;// Prescaler = 1024
TIMSK = 0x01;// Enable tomer overflow 0 interrupt
sei();// Global interrupt enable
}
SIGNAL(SIG_OVERFLOW0)
{
if (count < 5)
{
count++;
else
{
count = 0;
toggle = toggle ^ 0xff;
PORTA = toggle;
}
TCNT0 = 0;;
}
main()
{
init();
count = 0;
toggle = 0;
while(1);