A Timer/Counter is actually a register which increases/decreases automatically according to the logic you provided. In AVR there are two types of timers
- 8 Bit timer
- 16 Bit timer
Now what is the meaning of 8bits? As we already learn that 1byte is equal to 8bit. Now the formula of counting is-
n bit=2^n So 8 bit= 2^8=256
In real world we begin our counting from 1, but in computer world the counting begins from 0. So that in 8 bit the counting begin from 0 and the maximum value is 255 or in number from 0b11111111/0xFF. So those in 16 bit counters the counting begins from 0 or 0x0000 and maximum value 65535 or 0xFFFF. The whole operation of Timer/Counter depends on three elements-
- BOTTOM-The counter reaches the BOTTOM when it becomes 0x00
- MAX- The counter reaches its MAXimum when it becomes 0xFF (8 bit Timer) or 0xFFFF (16 bit timer).
- TOP- The counter reaches the top when it becomes equal to the highest value in the count sequence. The TOP value can be assigned to one of the fixed values : 0x00FF, 0x01FF or 0x03FF, or to the value stored in the OCRA or OCRx register of 16 bit counter/ the TOP can be value assigned 0xFF or the value store in the OCRx register for 8 bit counter.
Here come the fuse bit set up and F_CPU part. In makefile we can see the F_CPU. By default ATmega32 has F_CPU= 1MHz=1000000Hz and ATmega8 has F_CPU=8MHz=8000000Hz in internal oscillator. For proper operation it is necessary to set the HFUSE and LFUSE bit or we can calculate from default F_CPU value. The frequency of internal oscillator is not perfectly equal to the external crystal oscillator. There are counting error occur in internal oscillator, but external oscillator is nearly give the correct frequency. It is advise you to use the external crystal oscillator and make an appropriate setting to FUSE bit, since it set once and no need to set every time. For crystal setting The FUSE bit as follow-
HFUSE=0xc9 & LFUSE=0xEF
The relationship between time and frequency is
T=1/ (F_CPU) s =1/(F_CPU/Prescaling ) s = Prescaling/ F_CPU s
Here prescaler is nothing but division factor of main scale. We will discuss later about prescaler. The maximum count is-
Maximum count time = (Prescaler/F_CPU)*(2^n) where n= 8bit or 16bit
After maximum count the timer start from zero and this is timer overflow, i.e. for F_CPU=8HHz, prescaler = 1024 and 8bit timer
Maximum count time= (1024/8MHz)*(2^8) =32.768ms
If our desire millisecond is less than the overflow, then we can calculate required delay as follow-
Required delay time=(prescaler/F_CPU)*(Timer Count +1)
or, Timer count = Required delay *(F_CPU/Prescaler)-1
Let’s begin our journey with 8bit timer (timer0). Here the available register for Timer0
Timer/Counter Register – TCNT0
8 bit register. If we assign some value say 0x3F than TCNT0 start counting from zero and end at 0x3F.
Output Compare Register – OCR0
The output compare register contains an 8bit value that is continuously compared with the TCNT0 value. A match can be used to generate an output compare interrupt or to generate a waveform output to the OC0 pin.
Note that all the flag registers bit is set (1) when the corresponding Interrupt occurs and it is cleared by hardware when executing the corresponding interrupt handling vector. It can also clear by writing one to it.
In this article we discuss about the timer compare and overflow mode. In the normal mode operation àWGM00 and WGM01 clear. We already develop the timer count for require delay
Timer count=(Required delay )*(F_CPU/Prescaler)-1
Let make a 100ms delay with Timer0 and we have a crystal of 1MHz and prescaler 1024, then
Timer count=(100ms)*(1MHz/1024)-1 =96.65 ≈97
Let’s make a program to Toggle PORTC of ATmega32 after 100ms delay. The coding is as follow-
We also develop with Timer1 and Timer2. Download the programs and you will understand what happen.