On the ATmega168, there are three timers: two 8-bit timers and one 16-bit timer.
Timer/Counter 0 – 8 bit (Max value = 255)
Timer/Counter 1 – 16 bit (Max value = 65535)
Timer/Counter 2 – 8 bit (Max value = 255)
Timers and Interrupts
One of the way to use timers on the AVR is to have the timer initiate an interrupt at regular time intervals allowing the AVR to stop what it is doing and execute a short subroutine called an Interrupt Service Routine (ISR) before returning back to its main program.
First of all, however, when one needs the AVR to use any interrupts including timer-generated ones, the global interrupt bit needs to be set which can be simply done using a single line of C code somewhere at the beginning of the program:
sei ();
When the timer reaches the maximum value in its counter register (0xFF / 255 for an 8-bit timer; 0xFFFF / 65,535 for a 16-bit timer), the timer resets back to 0 and is said to have ‘overflowed’. A timer can be set to activate an interrupt every time it overflows. To do this on an ATMega168, one needs to set specific bits in the Timer/Counter Interrupt Mask register, TIMSK0.
Timer/Counter 0
Register Summary:
TIMSK0 : sets the timer to activate on overflow
TCCR0B : sets the prescalar (which also starts the timer)
The TIMSK0 register on the ATmega168
The TIMSK0 register
For Timer/Counter 0, the Timer Overflow Interrupt Enable bit or TOIE0 bit in the TIMSK0 register is the bit that sets the timer to initiate an interrupt every time it overflows when it reaches 255 and resets back to 0.
Timer/Counter 0 is an 8-bit timer which means that it can have a maximum value of:
Binary: 1111 1111
Hexadecimal: FF FF
Decimal : 255
The timer, when started, counts up from zero at the speed of the clock that is running the AVR. So for example if you have a 16MHz crystal, then the timer will be counting up at 16 million ticks per second (with each tick equivalent to adding 1 to the timer) but since this timer can only count up to 255, every time it reaches 255, it will simply cycle back to zero and start counting up again – passing through 255 many times (16 million / 255) within each second.
These sorts of timer counting speeds can mean that the timer is counting up too fast for some real world applications, so to slow it down to a more manageable number, clock selection bits can be set in the Timer Counter Control Register, TCCR0B (see figure) that can divide the AVR clock speed by certain preset values (see Table 12-9 below from the ATmega168 datasheet).
The TCCR0B Register on Atmel’s Atmega168 AVR
The TCCR0B Register
Clock Selection Bits
By setting (1) or clearing (0) the last 3 bits of the TCCR0B register, you can start and stop the timer, and you can decide the Timer 0 prescaler or the value that the clock source should be divided by to which the counter ticks up. For example, setting the CS02 bit to 0, the CS01 bit to 1 and the CS00 bit to 0 divides the clock source by 8, in the case of a 16MHz crystal, this would mean:
16,000,000 / 8 = 2,000,000
and therefore the timer will count up by 2 million ticks every second. Since there are 255 ticks in the counter before it overflows and sets off an interrupt, that means it overflows:
2,000,0000 / 255 ≃ 7843 times in a second
which means that the timer interrupt will be going off every
1 / 7843 ≃ 0.00013 seconds
The actual ticking counter occurs in the TCNT0 register with each tick adding 1 to the previous setting up to its maximum value (0b11111111, 0xFFFF, 255) at which point it resets back to 0 and then begins the count up again, so:
00000000 -> 00000001 -> 00000010 -> 00000011 … etc … 11111110 -> 11111111 -> 00000000 -> 00000001 … etc
The TCNT0 register on Atmel’s Atmega168 AVR microcontroller
The TCNT0 Register
Timer/Counter 1
Register Summary:
TIMSK1 : sets the timer to activate on overflow
TCCR1B : sets the prescalar (which also starts the timer)
Timer / Counter 1 is a 16-bit timer, therefore its maximum value is 65,535. So for a 16 MHz crystal with the maximum prescaler of 1024:
16,000,000 / 1024 = 15,625
and therefore the timer 1 will count up by 15,625 ticks every second. Since there are 65,535 ticks in the counter before it overflows and sets off an interrupt, that means it overflows once every:
65,535 / 15,625 ≃ 4.19 seconds
The TIMSK1 register on Atmel’s ATmega168 AVR microcontroller
The TIMSK1 Register
For Timer/Counter 1, the Timer Overflow Interrupt Enable bit or TOIE1 bit in the TIMSK1 register is the bit that sets the timer to initiate an interrupt every time it overflows when it reaches 65,535 and resets back to 0.
By setting (1) or clearing (0) the last 3 bits of the TCCR1B register, you can start and stop the timer, and you can decide the Timer1 prescaler or the value that the clock source should be divided by to which the counter ticks up:
The TCCR1B Register on Atmel’s Atmega168 AVR microcontroller
The TCCR1B Register
Timer1 clock selection bits
Using an Online Calculator by Frank Zho, for a 15MHz Crystal, the maximum delay with the 16-bit timer 1 is approximately 4.47 seconds:
AVR Calculator
Interrupt Service Routine Vectors
Timer / Counter 0 => ISR (TIMER0_OVF_vect)
Timer / Counter 1 => ISR (TIMER1_OVF_vect)
C Code Summary for Timer / Counter 1
int count = 0;
ISR (TIMER1_OVF_vect)
{
count++
if (count >15)
{
DDRB |= (1<<PB0); // makes PB0 an output
PORTB |= (1<<PB0); // putting the GREEN LED->1 on
ds18b20_temp = therm_read_temperature();
logi( ds18b20_temp );
DDRB &= ~(1<<PB0); // makes PB0 an input
PORTB &= ~(1<<PB0); // putting the GREEN LED->0 off
make_tcp_syn_from_any(buf); //SEND SYN PACKET TO AVR_SERVER TO INITIATE HANDSHAKE
count = 0;
}
}
TIMSK1 |= (1 << TOIE0); // set Timer T1 (16-bit) to cause an interrupt every time it overflows
TCCR1B |= (1 << CS12) | (1 << CS10); // set prescaler to 1024 and start the timer -> interrupt every 4.19 seconds (16MHz xtal)
sei(); // turn on interrupts
– when code is running through network communications – stop interrupts or stop the timer