5a-AVR-Timers (8 Bit)
5a-AVR-Timers (8 Bit)
5a-AVR-Timers (8 Bit)
Lecture 5a
Timers/Counters in Atmega16
◼ Atmega16 has three timers/counters
❑ 8-bit Timer/Counter0
❑ 16-bit Timer/Counter1
❑ 8-bit Timer/Counter2
2 / 39
Timers/Counter Functions
◼ The Timers can be used for the following
functions
❑ Normal Mode (Delay generation or Measuring
time)
❑ Clear timer on compare match CTC (Delay
generation or Measuring time) (Auto reload)
❑ Count External events
❑ PWM generation
◼ Phase correct PWM
◼ Fast PWM
❑ Waveform Generation using Normal and CTC
mode
3 / 39
Registers Associated with Timers
◼ Timer/Counter Control Register – TCCR0
4 / 39
Registers Associated with Timers
◼ Timer/Counter Register – TCNT0
The Timer/Counter Register gives direct access, both for read and
write operations, to the Timer/Counter unit 8-bit counter
◼ Output Compare Register – OCR0
5 / 39
Registers Associated with Timers
◼ Timer/Counter Interrupt Flag Register – TIFR
6 / 39
Flags Associated with Timers
◼ Timer/Counter Interrupt Flag Register – TIFR
7 / 39
Timer/Counter0 Interrupts
◼ Timer/Counter Interrupt Mask Register – TIMSK
9 / 39
ISR For Timers/Counter0
◼ ISR For Timer Overflow Interrupt
ISR(TIMER0_OVF_vect)
{
…..
}
10 / 39
Associated PIN with Timer 0
Timer 0 Input
PWM Channel
timer0
11 / 39
Selection of Modes
◼ TCCR0 (Timer/counter Control Register)
Selects mode of Timer
15 / 39
Normal Mode (1)
◼ TCCR0(Timer/counter Control Register)
Selects mode of Timer
❑ WGM00=0
16 / 39
Normal Mode
TOV0
17 / 39
Normal Mode
◼ Normal Mode(WGM01=0 & WGM00=0)
❑ The simplest mode of operation is the normal mode
❑ In this mode the counting direction is always up
(incrementing)
❑ The counter simply overruns when it passes its
maximum 8-bit value (TOP = 0xFF) and then restarts
from the bottom (0x00)
18 / 39
Normal Mode
◼ Normal Mode(WGM01=0 & WGM00=0)
❑ In normal operation the Timer/Counter Overflow
Flag(TOV0) will be set in the same timer clock cycle
as the TCNT0 becomes zero
❑ This mode can be used to create delays or measure
time between two events.
19 / 39
Normal Mode
20 / 39
8-bit Timer/Counter0
◼ Clock Source Select
❑ The Timer/Counter can be clocked by an internal or an
external clock source
❑ The clock source is selected by the clock select (CS02:0)
bits located in the Timer/Counter Control Register (TCCR0)
Timer/Counter Control Register – TCCR0
22 / 39
Calc of No for TCNT0 Register
◼ Procedure
❑ Nc = Time of delay (us) x Crystal freq (MHz)
❑ If Nc < 256 use Timer0 without prescaler else use prescaler.
❑ Nr = 256 – Nc (value to be loaded in TCNT0)
23 / 39
Example
Use Timer0 in normal mode to create a delay of
25us. Controller frequency is 8mhz. Calc number
for TCCR0 (pre-scaler), TCNT0;
◼ Solution
❑ Nc = 25u x 8M = 200
❑ Nc<256, hence no prescaler is required.
❑ Nr = 256-200 = 56
24 / 39
Example
◼ Generate a delay of 5ms using Timer0. Controller
frequency is 8Mhz. Calculate value of Pre-scaler and
TCNT0.
◼ Solution
❑ Nc = Time of delay (us) x Crystal freq (MHz)
❑ Nc = 5000x8 =40,000
❑ NC > 256 use Timer0 with prescaler
❑ Np = Nr / prescaler
❑ Np = 40000 / 8=5000
❑ Since, Np > 256 we choose the next prescaler value
❑ Np = 40000 / 64=625
❑ Np is still > 256 we choose the next prescaler value
❑ Np = 40000 / 256=156.25
❑ Nr = 256- Np
25 / 39
Example
◼ Timer0 is operated in normal mode with a prescaler of 1024.
Calculate the max delay generated (in ms). Controller frequency
is 8Mhz.
◼ SOLUTION
❑ Nc = Time of Delay(Td) x (Crystal Frequency/Prescaler)
❑ Td = (Nc x Prescaler)/ Crystal Frequency
❑ Td = (256 x 1024)/8
❑ Td = 32768us = 32.768ms
28 / 39
Example – Normal Mode (using interrupt)
#include<avr/io.h>
#include<avr/interrupt.h>
int main()
{
DDRB=0xFF;
TCNT0=186;
TIMSK=0x01;
SREG|=0x80;
TCCR0=0x02;
while(1)
{
}
}
ISR(TIMER0_OVF_vect)
{
PORTB=PORTB^0x10;
TCNT0=186; AVR_Normal_mode_Int
}
30 / 39
Clear Timer on Compare Match (2)
31 / 39
Clear Timer on Compare Match (CTC) (2)
◼ TCCR0(Timer/Counter Control Register)
Selects mode of Timer
32 / 39
Clear Timer on Compare Match
◼ In Clear Timer on Compare or CTC mode the OCR0
Register is used to manipulate the TIMER/COUNTER
resolution
◼ In CTC mode the counter is cleared to zero when the
counter value (TCNT0) matches the OCR0
◼ The OCR0 defines the top value for the counter, hence
also its resolution
◼ It also simplifies the operation of counting external
events
34 / 39
Clear Timer on Compare Match (CTC)
◼ An interrupt can be generated each time the counter
value reaches the TOP value by using the OCF0 flag
◼ If the interrupt is enabled, the interrupt handler routine
can be used for updating the TOP value
◼ If the new value written to OCR0 is lower than the
current value of TCNT0, the counter will miss the
compare match. The counter will then have to count to
its maximum value (0xFF) and wrap around starting at
0x00 before the compare match can occur
35 / 39
Example
◼ Write a C program to toggle only the PORTB.4 bit
continueously every 70 us. Use Timer0, CTC mode and
1:8 Prescaler to create the delay. Assume XTAL= 8 MHz.
36 / 39
Example CTC Mode (using interrupt)
#include<avr/io.h> #include<avr/io.h>
#include<avr/interrupt.h> #include<avr/interrupt.h>
int main() int main()
{ {
DDRB=0xFF; DDRB=0xFF;
TCCR0=0x0a; TCCR0=0x02;
OCR0=70; TCNT0=186;
TIMSK=0x02; TIMSK=0x01;
SREG|=0x80; SREG|=0x80;
while(1) while(1)
{} {}
}
}
ISR(TIMER0_COMP_vect) ISR(TIMER0_OVF_vect)
{ PORTB=PORTB^0x10; { PORTB=PORTB^0x10;
TCNT0=186;
} }
AVR_CTC_mode_Int 37 / 39
Counter Mode (3)
◼ The above two modes are used to drive the timer from
an external clock source.
◼ By using these options the timer can be used as a
counter to count external events.
38 / 39
Example
◼ Count the number of cars passing on the road. A sensor
is placed across the road, that sends a pulse when it
senses a car, attached to pin PB0. Configure the timer
so that it responds to the rising edge. Output the number
of cars on PORTA
◼ Solution
For this we configure the timer to count on the rising edge of an
external source. Hence, CS02=1,CS01=1,CS00=1. (Clock
Select)
The number of cars that pass through the road will be equal to
the value of TCNT0.
39 / 39
Solution - Code
#include<avr/io.h>
int main()
{
DDRA=0xFF;
DDRB=0x00;
TCCR0=0x07;
while(1)
{
PORTA=TCNT0;
}
}
AVR_Counter_Int.c
Timer_counter.isis
40 / 39