Probably Timer/Counters are complex peripherals in , but as fact they are most commonly used no matter what complexity program is. Designers of timers have put a lot of thought in them making them very flexible, versatile for all timing dependent tasks like measuring time periods, generating , generating output signals and timed interrupts.
Timers run independently from AVR core. Once set, they just do their silent job while AVR can do other tasks or simply go to sleep. AVR can read timer values, or change when ever it needs or simply can be interrupted with several available interrupts. If you see application where frequency is measured, music is generated or motor is driven – there is definitely timer involved.
8 bit and 16 timers
AVR microcontrollers usually have three or even more timers. Atmega328 (also ATmega48, ATmega88 and Atmega168) has two 8-bit timers and one 16-bit timer. Each of them can be configured individually with different rates and functions. Like, one can generate PWM, other measure count pulses, and third debounce buttons. Simply speaking 8 bit timers can count up to 255 counts while 16 bit timer can count to 65365. Once these values are reached, timers start over from 0. This is called timeroverflow. All of these can be set with some thresholds to trigger interrupts. Usually thresholds are set with Output Compare Registers OCR. When set timer will count and compare its current value with OCR and if match – timer will generate an interrupt.
Speaking of timers all three have partially similar functionality and also each contain special functions. So we can’t apply same approach to all of them. So wee will need to discuss them separately later.
Timer/Counter clock sources
Before getting to more details lets discuss one important vital part of timers – clock source. In order to make timer count we need to provide it with clock source. Generally speaking all timers can count synchronously to AVR core and asynchronously. Synchronous counting means that timer is tied to FCPU clock source directly or prescalled. If microcontroller is clocked with 16MHz crystal then timer ticks according to this source. In asynchronous counting mode timer is clocked from external clock source: T0 pin for Timer/Counter0, T1 pin for Timer/Counter1 and TOSC1 pin for Timer/Counter2.
Speaking of Timer/Counter2 – it can be set to run as Real Time Clock (RTC) with external 32.768KHz crystal.
Prescaller simply speaking is a 10-bit binary counter that scales down clock source by dividing frequency by power factor of 2. This way can have longer time counts but we sacrifice a resolution for this. For instance lets take a self descriptive image of Atmega328 TimerCounter2 prescaller.
You can see that no matter what timer clock source is selected it goes through prescaller part where it can divided by 8, 32, 64, 128, 256, and 1024. which prescaling factor is selected depends on bits CS20, CS21 and CS22 set in TCCR2B. For other timers this is pretty similar.
With prescallers you can have longer counting times and this way avoid intervention of software to prolong counting with . For instance, if MCU is clocked at 1MHz without prescaller counter fills up to 255 value very fast – in 256µs, while with prescaller 1028 it will fill up in ~0.26s. It is easy to calculate these values if you know what timer resolution is. Simply speaking – resolution is a smallest time period of one timer count. It can be easily calculated by using simple formula:
So if microcontroller is clocked with 1MHz source, then 8 bit timer without prescaller will run with resolution:
so if timer is counts 256 ticks until overflow then it takes:
If we use 1024 prescaller we get:
Then to count up to overflow takes:
If you need higher resolution and longer times then consider using 16-bit timer or do this with help of firmware.