0% found this document useful (0 votes)
9 views33 pages

IT343 Lecture 05

The document discusses the functionality and operation of timers and counters in AVR microcontrollers, specifically focusing on Timer0 and Timer2 in the ATmega328. It explains how timers can generate delays and count events using an oscillator or external sources, detailing the registers involved and their configurations. Additionally, it provides examples of programming techniques for generating time delays and square waves using different modes of operation, including normal and CTC modes.

Uploaded by

nevrixai
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views33 pages

IT343 Lecture 05

The document discusses the functionality and operation of timers and counters in AVR microcontrollers, specifically focusing on Timer0 and Timer2 in the ATmega328. It explains how timers can generate delays and count events using an oscillator or external sources, detailing the registers involved and their configurations. Additionally, it provides examples of programming techniques for generating time delays and square waves using different modes of operation, including normal and CTC modes.

Uploaded by

nevrixai
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

Timer/Counter

In AVR
Lecture 5
A generic timer/counter
Delay Generating - 1
Oscillator 0
◼ COUT
Counter register
External 1
source
Flag
Counter/Timer

• When we want to generate time delays, we connect the oscillator to the clock
pin of the counter. So, when the oscillator ticks, the content of the counter is
incremented. As a result, the content of the counter register represents how
many ticks have occurred from the time we have cleared the counter. Since
the speed of the oscillator in a microcontroller is known, we can calculate the
tick period, and from the content of the counter register we will know how
much time has elapsed. So, one way to generate a time delay is to clear
(reset) the counter at the start time and wait until the counter reaches a
certain number.

➢ For example, consider a microcontroller with an oscillator with frequency of


1 MHz; in the microcontroller, the content of the counter register increments
once per microsecond. So, if we want a time delay of 100 microseconds, we
should clear the counter and wait until it becomes equal to 100.
2
A generic timer/counter (Cont..1)
Delay Generating - 2
Oscillator 0
◼ COUT
Counter register
External 1
source
Flag
Counter/Timer

• In the microcontrollers, there is a flag for each of the counters. The flag is set
when the counter overflows, and it is cleared by software. The second
method to generate a time delay is to load the counter register and wait until
the counter overflows and the flag is set.

➢ For example, in a microcontroller with a frequency of 1 MHz, with an 8-bit


counter register, if we want a time delay of 3 microseconds, we can load the
counter register with $FD and wait until the flag is set after 3 ticks. After the
first tick, the content of the register increments to $FE; after the second tick,
it becomes $FF; and after the third tick, it overflows (the content of the
register becomes $00) and the flag is set.

3
A generic timer/counter (Cont..2)
Counting
Oscillator 0
◼ COUT
Counter register
External 1
source
Flag
Counter/Timer

• Many applications need to count an event. So, there are counter registers in
microcontrollers for this purpose. When we want to count an event, we
connect the external event source to the clock pin of the counter register.
Then, when an event occurs externally, the content of the counter is
incremented; in this way, the content of the counter represents how many
times an event has occurred.

4
Timers in AVR
◼ 1 to 6 timers: referred to as Timers 0, 1, 2, 3, 4, and 5
◼ 3 timers (Timer0, Timer1, and Timer2) in ATmega328

◼ 8-bit and 16-bit timers


◼ two 8-bit timers (Timer0 and Timer2) and one 16-bit timer
(Timer1) in ATmega328

5
Timer in AVR (Cont..1)
◼ Every timer needs a clock pulse to tick.

◼ The clock source can be internal or external.

◼ If we use the internal clock source, then the frequency of the


crystal oscillator is fed into the timer. Therefore, it is used for
time delay generation and consequently is called a timer.

◼ By choosing the external clock option, we feed pulses


through one of the AVR’s pins. This is called a counter.

Oscillator
Counter register
External
source
Flag
Counter/Timer

6
Timer in AVR (Cont..2)
For each of the timers, there is basic:
◼ TCNTn (Timer/Counter register)

◼ TOVn (Timer Overflow flag)

◼ TCCRn (Timer Counter control register)

◼ OCRn (Output Compare register) TCCRn

◼ OCFn (output compare match flag)


TCNTn OCRn

TOVn
=
Comment:
All of the timer registers are
byte-addressable registers OCFn

7
Timer in AVR (Cont..3)
◼ TCNTn (Timer/Counter) register
➢ Upon reset, it contains zero.
➢ It counts up with each pulse.
➢ The contents of the timers/counters can be accessed using it.
➢ Can load a value into it or read its value.

◼ TOVn (Timer Overflow) flag


➢ When a timer overflows, its TOVn flag will be set.

◼ TCCRn (Timer Counter Control Register)


➢ For setting modes of operation.
➢ For example, can specify Timer0 to work as a timer or a
counter by loading proper values into the TCCR0.
8
Timer in AVR (Cont..4)
◼ OCRn (Output Compare Register)
➢ Its content is compared with the content of the TCNTn. When
they are equal the OCFn (Output Compare Flag) flag will be
set.

◼ OCFn (Output Compare Match Flag)

◼ All these timer registers are located in the I/O register


memory.

9
Timer 0 (an 8-bit timer)
Timer 0
◼ Timer0 is 8-bit in ATmega32; thus, TCNT0 is 8-bit as shown

◼ TCCR0 is an 8-bit register used for control of Timer0.

◼ CS02:CS00 (Timer0 clock source).


➢ If CS02:CS00 = 000, then the counter is stopped.

➢ If CS02–CS00 have values between 001 and 101, the oscillator

is used as clock source and the timer/counter acts as a timer.


In this case, the timers are often used for time delay.
➢ If CS02–CS00 are 110 or 111, the external clock source is used

and it acts as a counter.


11
Timer 0 (Cont..1)
COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00 TCCR0A

FOC0A FOC0B - - WGM02 CS02 CS01 CS00 TCCR0B

Clock Selector (CS)

CS02 CS01 CS00 Comment


0 0 0 No clock source (Timer/Counter stopped)
0 0 1 clk (No Prescaling)
0 1 0 clk / 8
0 1 1 clk / 64
1 0 0 clk / 256
1 0 1 clk / 1024
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

12
Timer 0 (Cont..2)
◼ TCCR0 is an 8-bit register used for control of Timer0.

◼ Timer0 can work in four different modes, the WGM01 and


WGM00 bits are used to choose one of them.

13
Timer 0 (Cont..3)
◼ Normal Mode
I. The content of the timer/counter TCNT0

increments with each clock.


0xFF
II. It counts up until it reaches its
TOV TOV TOV
max of 0xFF. 0 time

III. When it rolls over from 0xFF to

0x00, it sets high a flag bit


called TOV0 (Timer Overflow).
FF
FE TOV0: 0
1

2
1
0 TOV0 = 1
14
Timer 0 (Cont..4)
◼ TIFR (Timer/counter Interrupt Flag Register)

➢ The TOV0 (Timer0 Overflow) flag is set when the counter


overflows, going from $FF to $00 and it remains set until the
software clears it.
➢ In order to clear it we need to write 1 to it, indeed this rule
applies to all flags of the AVR chip.
15
Timer 0 (Cont..5)

16
Finding values to be loaded into the timer
1. Calculate the period of clock source.
◼ Period = 1 / Frequency
◼ E.g. For XTAL = 16 MHz ➔ T = 1/16MHz
2. Divide the desired time delay by period of
clock.
3. Perform 256 - n, where n is the decimal
value we got in Step 2.
4. Set TCNT0 = 256 - n

17
Example 1: Write a program that waits 14 machine
cycles in Normal mode
$100
- - - - - OCF0B OCF0A TOV0 TIFR0
-$0E
$F2
DDRB = 1<<5; calculate the delay, if
PORTB &= ~(1<<5); //PB5=0 XTAL = 10 MHz.
while (1) Solution:
{
1) Calculating T:
TCNT0 = 0xF2;
T = 1/f = 1/10M = 0.1µs
TCCR0A = 0x00;
TCCR0B = 0x01; 2) Calculating num of
while((TIFR0&(1<<TOV0))==0) machine cycles:
{} $100
TCCR0B = 0; -$F2
TIFR0 = (1<<TOV0);
$0E = 14
PORTB ^= (1<<5);
} 3) Calculating delay
PORTB=PORTB ^ 0b00100000 14 * 0.1µs = 1.4 µs
18
Example 2: Assuming that XTAL = 10 MHz, write a program to generate a
square wave with a period of 10 µs on pin PORTB.3.
◼ For a square wave with T = 10 µs we must have
a time delay of 5 µs.

◼ Because XTAL = 10 MHz, the clock period is 0.1 DDRB = 1<<3;


µs.
PORTB &= ~ (1<<3);

◼ This means that we need 5 µs / 0.1 µs = 50 while (1)


clocks. {
◼ Then, we load the counter register TCNT0 by TCNT0 = 206;
256 - 50 = 206.
TCCR0A = 0x00;
TCCR0B = 0x01;
while((TIFR0&0x01) == 0)
{}
TCCR0B = 0;
TIFR0 = 1<<TOV0;
PORTB = PORTB ^ (1<<3);
}

19
Example 3: Modify TCNT0 in Example 2 to get the largest time delay possible with no prescaler.
Find the delay in µs. In your calculation, do not include the overhead due to instructions.

◼ To get the largest delay we make TCNT0 zero. This will


count up from 00 to 0xFF and then roll over to zero.
DDRB = 1 << 3;
PORTB &= ~(1<<3);
while (1)
Solution {
1) Calculating T: TCNT0 = 0x00;
TCCR0A = 0x00;
T = 1/f = 1/10MHz = 0.1µs
TCCR0B = 0x01;
2) Calculating delay
while((TIFR0&(1<<TOV0))==0)
256 * 0.1µs = 25.6µs
{}
TCCR0B = 0;
TIFR0 = 0x01;
PORTB = PORTB^(1<<3);
}

20
21
Generating Large Delays
◼ Using loop
◼ Prescaler
◼ Bigger counters

22
Prescaler and generating a large time delay

PSR10

Clear
clkIO 10-bit T/C Prescaler

clk/8
clk/64
clk/256

clk/1024
T0
0

CS00 0 1 2 3 4 5 6 7
CS01
CS02

Timer/Counter0 clock
source

23
CTC (Clear Timer on Compare match) mode
TCNT0
0xFF
OCR0

OCF0 OCF0 OCF0


0 time

OCR0 0
xx TOV0:

2 0
1
OCF0:
1
TOV0 = no change
0
OCF0 = 1
24
CTC mode (Cont.)
COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00 TCCR0A
1 0
FOC0A FOC0B - - WGM02 CS02 CS01 CS00 TCCR0B

0
Timer Mode (WGM)
WGM02 WGM01 WGM00 Comment
0 0 0 Normal
0 0 1 Phase correct PWM
0 1 0 CTC
0 1 1 Fast PWM
1 0 0 Reserved
1 0 1 Phase correct PWM
1 1 0 Reserved
1 1 1 Fast PWM

25
Rewrite example 2 using CTC
Example 4: Rewrite example 2 using CTC
(Assuming XTAL = 10MHz, write a program to generate a square wave with a period of 10 ms.)

- - - - - OCF0B OCF0A TOV0 TIFR0

◼ For a square wave with T = 10 µs we


must have a time delay of 5 µs.
DDRB |= 1<<3;

◼ Because XTAL = 10 MHz, the counter while (1)


counts up every 0.1 µs. {
OCR0A = 49;
◼ This means that we need 5 µs / 0.1 µs = TCCR0A = (1<<WGM01); //CTC
50 clocks. TCCR0B = 1; //N = 1
while((TIFR0&(1<<OCF0A))==0)
◼ Therefore, we have OCR0A= 49.
{ }
TCCR0B = 0; //stop timer0
TIFR0 = 1<<OCF0A;
PORTB ^= 1<<3; //toggle PB3
}

26
The difference between Timer0 and Timer2
◼ Timer0 ◼ Timer2

CS02 CS01 CS00 Comment CS22 CS21 CS20 Comment


0 0 0 Timer/Counter stopped 0 0 0 Timer/Counter stopped
0 0 1 clk (No Prescaling) 0 0 1 clk (No Prescaling)
0 1 0 clk / 8 0 1 0 clk / 8
0 1 1 clk / 64 0 1 1 clk / 32
1 0 0 clk / 256 1 0 0 clk / 64
1 0 1 clk / 1024 1 0 1 clk / 128
1 1 0 External clock (falling edge) 1 1 0 clk / 256
1 1 1 External clock (rising edge) 1 1 1 clk / 1024

27
Counting
Counting
PSR10

Clear
clkIO 10-bit T/C Prescaler

clk/8
clk/64
clk/256

clk/1024
T0
0

CS00 0 1 2 3 4 5 6 7
CS01
CS02 28 pin
(PCINT14/RESET) PC6 1 28 PC5 (ADC5/SCL/PCINT13)
(PCINT16/RXD) PD0 2 27 PC4 (ADC4/SDA/PCINT12)
Timer/Counter0 clock
(PCINT17/TXD) PD1 3 26 PC3 (ADC3/PCINT11)
source
(PCINT18/INT0) PD2 4 MEGA328 25 PC2 (ADC2/PCINT10)
(PCINT19/OC2B/INT1) PD3 5 24 PC1 (ADC1/PCINT9)
T0 PD4
(PCINT20/XCK/T0) 6 23 PC0 (ADC0/PCINT8)
VCC 7 22 GND
GND 8 21 AREF
(PCINT6/XTAL1/TOSC1) PB6 9 20 AVCC
6 (PCINT7/XTAL2/TOSC2) PB7 10 19 PB5 (SCK/PCINT5)
(PCINT21/OC0B) PD5 11 18 PB4 (MISO/PCINT4)
(PCINT22/OC0A/AIN0) PD6 12 17 PB3 (MOSI/OC2A/PCINT3)
(PCINT23/AIN1) PD7 13 16 PB2 (SS/OC1B/PCINT2)
7 (PCINT0/CLKO/ICP1) PB0 14 15 PB1 (OC1A/PCINT1)

29
Assuming that clock pulses are fed into pin T0, write a program for counter 0 in normal
mode to count the pulses on falling edge and display the state of the TCNT0 count on
PORTC.
#include <avr/io.h>
CBI DDRD,4 ;make T0 (PD4) input int main()
LDI R20,0xFF
{
OUT DDRC,R20 ;make PORTC output
LDI R20,0x00 DDRC = 0xFF;
OUT TCCR0A,R20 TCCR0A = 0; //WGM=0000 (Normal)
LDI R20,0x06
TCCR0B = 0x06; //CS=6 (Count on fall)
OUT TCCR0B,R20 ;counter, falling edge
AGAIN: while (1)
IN R20,TCNT0 {
OUT PORTC,R20 ;PORTC = TCNT0 PORTC = TCNT0; //read TCNT0
RJMP AGAIN ;keep doing it
}
}
PSR10

Clear
clkIO 10-bit T/C Prescaler
clk/8
clk/64
clk/256

clk/1024

COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00 TCCR0A


T0
0 FOC0A FOC0B - - WGM02 CS02 CS01 CS00 TCCR0B

CS00 0 1 2 3 4 5 6 7
CS01
CS02

Timer/Counter0 clock
source
30
Assuming that clock pulses are fed into pin T1. Write a program for Counter1 in CTC
mode to make PORTC.0 high every 100 pulses.
CBI DDRD,5 ;make T1 (PD5) input #include <avr/io.h>
SBI DDRC,0 ;PC0 as an output
int main()
LDI R20,0x00 {
OUT TCCR1A,R20 DDRD &= ~(1<<5);
LDI R20,0x0E ;CS=6 (falling edge counter)
OUT TCCR1B,R20 ;CTC DDRC |= 1<<0;
AGAIN: TCCR1A = 0; //WGM=0100 (CTC)
LDI R20,0
TCCR1B = 0x0E; //CS=6 (Count on fall)
OUT OCR1AH,R20 ;TEMP = 0
LDI R20,99 OCR1A = 99;
OUT OCR1AL,R20 ;ORC1L = R20, OCR1H = TEMP while (1)
L1:
{
SBRS TIFR1,OCF1A
RJMP L1 ;keep doing it while((TIFR1&(1<<OCF1A)) == 0);
LDI R20,1<<OCF1A ;clear OCF1A flag TIFR1 = (1<<OCF1A);
OUT TIFR1, R20
PORTC |= (1<<0); //PC0 = 1
SBI PORTC,0 ;PC0 = 1 PORTC &= ~(1<<0); //PC0 = 0
CBI PORTC,0 ;PC0 = 0
}
RJMP AGAIN ;keep doing it
}

31
32
The End

QUESTIONS?

33

You might also like