MPS - Ch09 - AVR - Timer Programming in Assembly and C
MPS - Ch09 - AVR - Timer Programming in Assembly and C
Refs:
1. The AVR microcontroller and embedded systems: using Assembly
and C, Muhammad Ali Mazidi, 2011 Pearson Education
2. Slides of Prof. Lam Phung, University of Wollongong
1
OBJECTIVES
Upon completion of this chapter, you will be able to:
• List the timers of the ATmega32 and their associated
registers
• Describe the Normal and CTC modes of the AVR timers
• Program the AVR timers in Assembly and C to generate
time delays
• Program the AVR counters in Assembly and C as event
counters
2
Outline
1. Overview of Timers in ATmega32
2. Programming Timers 0, 1, and 2
– Programming 8-bit Timers: Timers 0 and 2
– Programming 16-bit Timer: Timer 1
3. Counter Programming
4. Programming Timers in C
3
Introduction
• What is the meaning of timer ?
– Timers and counters is a microcontroller feature related by
time which count time or events or number of repetitions of
a specific event in a 8 bits (or a 16 bit) register to count
from 0 to 0xff (or to 0xffff).
4
Some Applications based on timer/counter
1. Digital clock, stopwatch, traffic light, propeller.
2. DC motor control using PWM mode.
3. Light control using PWM mode.
4. Counters (gates, traffics).
5. Frequency generator.
6. Frequency meter.
7. RTOS.
5
A generic timer/counter
• Generating delay
• Counting
• Generating waveform
• Capturing
Oscillator 0
Counter register
COUT
External 1
source
Flag
Counter/Timer
6
Overview of Timers in ATmega32
• ATmega32 has three timers: Timer 0, Timer 1 and Timer 2.
– two 8-bit timers: Timer 0 and Timer 2
– one 16-bit timer: Timer 1
• Each timer is associated with a counter and a clock signal.
• The clock signal of a timer can come from
– the internal system clock or
– an external clock source.
• When the internal system clock is used, a prescaler can be
used make the timer count at a slower rate.
• Example:
– Suppose the system clock rate = 1Mhz (1μs per cycle).
– Suppose a timer prescaler of 64 is used.
– Then, timer will increment every 64μs.
source
10
Outline
1. Overview of Timers in ATmega32
2. Programming Timers 0, 1, and 2
– Programming 8-bit Timers: Timers 0 and 2
• 8-bit timer
• Normal Mode
• CTC mode
– Programming 16-bit Timer: Timer 1
3. Counter Programming
4. Programming Timers in C
11
Outline
1. Overview of Timers in ATmega32
2. Programming Timers 0, 1, and 2
– Programming 8-bit Timers: Timers 0 and 2
• 8-bit timer
• Normal Mode
• CTC mode
– Programming 16-bit Timer: Timer 1
3. Counter Programming
4. Programming Timers in C
12
8-bit Timer/Counter0
• Timer/Counter0 is a general purpose, single compare unit,
8-bit Timer/Counter module.
Timer Speed
Output Compare Interrupt
14
Timer/counter 0 Registers
1. Timer counter register (TCNT0)
2. Output compare register (OCR0)
3. Timer/Counter control register (TCCR0)
4. Timer interrupt flag register (TIFR)
5. Timer interrupt mask register (TIMSK)
15
Timer counter register (TCNT0)
17
Timer/Counter Control register (TCCR0)
• TCCRn register controls the timer’s working mode
Clock signal
Force Output Compare Selection/configuration
Wave Generator
Mode control
Compare Output Mode:
Controls the way in which
the result of the comparison
unit is used – depends on
the wave generator mode
FOC0 (Force Output compare match): This is a write-only bit, which can be used
while generating a wave. Writing 1 to it causes the wave generator to act as if a
compare match had occurred
18
Clock signal selection
19
Bit 6, 3 – WGM01:0: Waveform Generation Mode
• These bits control the counting sequence of the counter, the
source for the maximum (TOP) counter value, and what type of
Waveform Generation to be used. Modes of operation supported
by the Timer/Counter unit are: Normal mode, Clear Timer on
Compare Match (CTC) mode, and two types of Pulse Width
Modulation (PWM) modes
20
Bit 5:4 – COM01:0: Compare Match Output Mode
• These bits control the Output Compare pin (OC0) behavior. If one
or both of the COM01:0 bits are set, the OC0 output overrides the
normal port functionality of the I/O pin it is connected to. However,
note that the Data Direction Register (DDR) bit corresponding to
the OC0 pin must be set in order to enable the output driver.
• When OC0 is connected to the pin, the function of the COM01:0
bits depends on the WGM01:0 bit setting. Table 39 shows the
COM01:0 bit functionality when the WGM01:0 bits are set to a
normal or CTC mode (non-PWM).
21
22
Figure 9-5. TCCRO (Timer/Counter Control Register) Register
23
24
Timer interrupt flag register (TIFR)
25
Timer interrupt mask register (TIMSK)
26
Counter unit
27
TOV0 (Timer0 Overflow)
• The flag is set when the counter overflows, going from
$FF to $00. As we will see soon, when the timer rolls
over from $FF to 00, the TOV0 flag is set to 1 and it
remains set until the software clears it.
• The strange thing about this flag is that in order to clear
it we need to write 1 to it. Indeed this rule applies to all
flags of the AVR chip.
• In AVR, when we want to clear a given flag of a
register we write 1 to it and 0 to the other bits.
For example, the following program clears TOV0:
LDI R20,0x01
OUT TIFR,R20 ;TIFR = 0b00000001
28
Outline
1. Overview of Timers in ATmega32
2. Programming Timers 0, 1, and 2
– Programming 8-bit Timers: Timers 0 and 2
• 8-bit timer
• Normal Mode
• CTC mode
– Programming 16-bit Timer: Timer 1
3. Counter Programming
4. Programming Timers in C
29
Normal mode
Normal Mode
• Increase TCNT from Bottom(0x00) TCNT0
to Max(0xff)
• Overflow Interrupt at Max TCNT 0xFF
• Restart from the Bottom when TOV TOV TOV
time
0
TCNT reaches to the Max
FF
FE TOV0: 0
1
2
1
0 TOV0 = 1
30
Steps to program Timer0 in Normal mode
• To generate a time delay using Timer0 in Normal mode, the
following steps are taken:
1. Load the TCNT0 register with the initial count value.
2. Load the value into the TCCR0 register, indicating which mode is
to be used and the prescaler option. When you select the clock
source, the timer/counter starts to count, and each tick causes
the content of the timer/counter to increment by 1.
3. Keep monitoring the timer overflow flag (TOV0) to see if it is
raised. Get out of the loop when TOV0 becomes high.
4. Stop the timer by disconnecting the clock source, using the
following instructions:
LDI R20,0x00
OUT TCCR0,R20 ;timer stopped, mode=Normal
5. Clear the TOV0 flag for the next round.
6. Go back to Step 1 to load TCNT0 again.
31
Example 1: Write a program that waits 14 machine
cycles in Normal mode.
14 = $0E UP
COUT
Counter Register Load
$100 8
-$0E $F2
$F2
0 0 0 0 1
PSR10
0 0 Normal
clk/8
clk/64
clk/256
clk/1024
0 1 CTC T0
0
1 0 PWM, phase correct
1 1 Fast PWM CS00 0 1 2 3 4 5 6 7
CS01
CS02
Timer/Counter0 clock
source
32
Example 1: write a program that waits 14 machine
cycles in Normal mode.
$100 FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00 TCCR0
-$0E OCF2 TOV2 ICF1 OCF1A OCF1B TOV1 OCF0 TOV0 TIFR
$F2
.INCLUDE "M32DEF.INC"
.INCLUDE "M32DEF.INC"
Solution 1 (inaccurate):
LDI R16,0x20
1) Calculating T: SBI DDRB,5 ;PB5 as an output
LDI R17,0
T = 1/f = 1/10M = 0.1µs OUT PORTB,R17
BEGIN: LDI R20,0xF2
2) Calculating num of OUT TCNT0,R20 ;load timer0
machine cycles: LDI R20,0x01
OUT TCCR0,R20 ;Timer0,Normal mode,int clk
$100 AGAIN: IN R20,TIFR ;read TIFR
SBRS R20,0 ;if TOV0 is set skip next inst.
-$F2 RJMP AGAIN
LDI R20,0x0
$0E = 14 OUT TCCR0,R20 ;stop Timer0
LDI R20,0x01
3) Calculating delay OUT TIFR,R20 ;clear TOV0 flag
34
Accurate calculating
Other than timer, executing the instructions consumes time; so if we
want to calculate the accurate delay a program causes we should add
the delay caused by instructions to the delay caused by the timer
LDI R16,0x20
SBI DDRB,5
LDI R17,0
OUT PORTB,R17
BEGIN: LDI R20,0xF2 1
OUT TCNT0,R20 1
LDI R20,0x01 1
OUT TCCR0,R20 1
AGAIN: IN R20,TIFR 1
SBRS R20,0 1/2
RJMP AGAIN 2
LDI R20,0x0 1
OUT TCCR0,R20 1
LDI R20,0x01 1
OUT TIFR,R20 1
EOR R17,R16 1
OUT PORTB,R17 1
RJMP BEGIN 2
18
Delay caused by timer = 14 * 0.1µs = 1.4 µs
Delay caused by instructions = 18 * 0.1µs = 1.8
Total delay = 3.2 µs ➔ wave period = 2*3.2 µs = 6.4 µs ➔ wave frequency = 156.25 KHz
35
Example 9-3 (1/3)
36
Example 9-3 (2/3)
37
Example 9-3 (3/3)
38
39
40
• We can develop a formula for delay calculations using the
Normal mode of the timer for a crystal frequency of XTAL =
8 MHz. This is given in Figure 9-8.
• The scientific calculator in the Accessories menu directory of
Microsoft Windows can help you find the TCNT0 value. This
calculator supports decimal, hex, and binary calculations.
See Example 9-6.
41
Example 9-6 (1/2)
42
Example 9-6 (2/2)
43
Finding values to be loaded into the timer
44
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 counter counts up every 0.1 µs. This means
that we need 5 µs / 0.1 µs = 50 clocks. 256 - 50 = 206.
.INCLUDE "M32DEF.INC"
DDRB = 1<<3;
LDI R16,0x08
PORTB &= ~ (1<<3);
SBI DDRB,3 ;PB3 as an output
LDI R17,0 while (1)
OUT PORTB,R17
{
BEGIN: LDI R20,206
OUT TCNT0,R20 ;load timer0 TCNT0 = 206;
LDI R20,0x01
TCCR0 = 0x01;
OUT TCCR0,R20 ;Timer0,Normal mode,int clk
AGAIN: IN R20,TIFR ;read TIFR while((TIFR&0x01) == 0);
SBRS R20,TOV0 ;if TOV0 is set skip next
TCCR0 = 0;
RJMP AGAIN
LDI R20,0x0 TIFR = 1<<TOV0;
OUT TCCR0,R20 ;stop Timer0
PORTB = PORTB ^ (1<<3);
LDI R20,0x01
OUT TIFR,R20 ;clear TOV0 flag }
EOR R17,R16 ;toggle D3 of R17
OUT PORTB,R17 ;toggle PB3
RJMP BEGIN
45
Example 9-7 (1/2)
46
Example 9-7 (2/2)
47
48
Using the Windows calculator to find TCNT0
49
Example 9-9 (1/2)
50
Example 9-9 (2/2)
51
Generating Large Delays
• Using loop
• Prescaler
• Bigger counters
52
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
59
Example 9-16 (1/3)
60
Example 9-16 (2/3)
61
Example 9-16 (3/3)
62
Outline
1. Overview of Timers in ATmega32
2. Programming Timers 0, 1, and 2
– Programming 8-bit Timers: Timers 0 and 2
• 8-bit timer
• Normal Mode
• CTC mode
– Programming 16-bit Timer: Timer 1
3. Counter Programming
4. Programming Timers in C
63
CTC (Clear Timer on Compare match) mode
TCNT0
0xFF
OCR0
OCR0 0
xx TOV0:
2 0
1
OCF0:
1
TOV0 = no change
0
OCF0 = 1
64
Example 3: Rewrite example 2 using CTC
Rewrite example 2 using CTC
FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00 TCCR0
• For a square wave with T = 10 µs we must have a time delay of 5 µs. Because
XTAL = 10 MHz, the counter counts up every 0.1 µs. This means that we need 5
µs / 0.1 µs = 50 clocks. Therefore, we have OCR0= 49.
.INCLUDE "M32DEF.INC" DDRB |= 1<<3;
LDI R16,0x08
PORTB &= ~(1<<3);
SBI DDRB,3 ;PB3 as an output
LDI R17,0 while (1)
OUT PORTB,R17
{
LDI R20,49
OUT OCR0,R20 ;load timer0 OCR0 = 49;
BEGIN: LDI R20,0x09
TCCR0 = 0x09;
OUT TCCR0,R20 ;Timer0,CTC mode,int clk
AGAIN: IN R20,TIFR ;read TIFR
SBRS R20,OCF0 ;if OCF0 is set skip next while((TIFR&(1<<OCF0))==0);
RJMP AGAIN
TCCR0 = 0; //stop timer0
LDI R20,0x0
OUT TCCR0,R20 ;stop Timer0 TIFR = 0x02;
LDI R20,0x02 ; or LDI R20, 1 << OCF0
PORTB.3 = ~PORTB.3;
OUT TIFR,R20 ;clear OCF0 flag
EOR R17,R16 ;toggle D3 of R17 }
OUT PORTB,R17 ;toggle PB3
RJMP BEGIN
65
Example 9-17 (1/2)
66
Example 9-17 (2/2)
67
68
69
70
71
CTC Mode
• Notice that the comparator checks for equality; thus, if
we load the OCR0 register with a value that is smaller
than TCNT0's value, the counter will miss the compare
match and will count up until it reaches the maximum
value of $FF and rolls over. This causes a big delay and
is not desirable in many cases. See Example 9-22.
72
Example 9-22 (1/2)
73
Example 9-22 (2/2)
OCR0
74
Timer2
• Timer0 • Timer2
TCCR0 TCCR2
TCNT0 TCNT2
TOV0 TOV2
= OCF0 = OCF2
OCR0 OCR2
75
76
The difference between Timer0 and Timer2
• Timer0 • Timer2
77
Outline
1. Overview of Timers in ATmega32
2. Programming Timers 0, 1, and 2
– Programming 8-bit Timers: Timers 0 and 2
• 8-bit timer
• Normal Mode
• CTC mode
– Programming 16-bit Timer: Timer 1
3. Counter Programming
4. Programming Timers in C
78
Timer 1 - Overview
• 16-bit counter.
• 10-bit prescaler: 8, 64, 256, 1024
• can trigger a timer overflow interrupt when counter
reaches MAX.
• can trigger an input capture interrupt when an event
occurs on the input capture pin.
– timer value is stored automatically in a register.
– input capture pin for Timer 1 is ICP1 (PD6).
• can trigger an output compare match interrupt when
timer reaches a preset value.
– There are two independent output compare channels
A and B.
79
Ref: Prof. Lam Phung, University of Wollongong
16-bit Timer/Counter Block Diagram
Ouput Compare
registers
Timer Control
registers
80
Timer 1 – Simplified block diagram
81
Timer 1 ─ Five groups of registers
82
Ref: Prof. Lam Phung, University of Wollongong
83
84
Figure 9-18. TCCR1B (Timer 1 Control) Register (1/3)
85
Figure 9-18. TCCR1B (Timer 1 Control) Register (2/3)
86
Figure 9-18. TCCR1B (Timer 1 Control) Register (3/3)
87
Timer 1 – Normal mode
88
Timer 1 – CTC mode
89
90
Example 9-27 (cont.d)
91
92
Example 9-29 (cont.d)
93
Accessing 16-bit registers (1/5)
• The AVR is an 8-bit microcontroller, which means it can
manipulate data 8 bits at a time, only. For example:
LDI R16, 0x12
OUT SPL, R16
LDI R16, 0x34
OUT SPH, R16 ;SP = 0x3412
• In 16-bit timers, however, we should read/write the entire
content of a register at once, otherwise we might have problems.
For example, imagine the following scenario:
– The TCNT1 register contains 0x15FF. We read the low byte of
TCNT1, which is 0xFF, and store it in R20. At the same time a timer
clock occurs, and the content of TCNT1 becomes 0x1600; now we
read the high byte of TCNT1, which is now 0x16, and store it in R21.
If we look at the value we have read, R21:R20 = 0x16FF. So, we
believe that TCNT1 contains 0x16FF, although it actually contains
0x15FF.
94
Accessing 16-bit registers (2/5)
96
Accessing 16-bit registers (4/5)
• Notice that according to the internal circuitry of the AVR, we should first write
into the high byte of the 16-bit registers and then write into the lower byte.
Otherwise, the program does not work properly. For example, the following code:
LDI R16, 0xFF
OUT TCNT1L, R16 ; TCNT1L = R16, TCNT1H = TEMP
LDI R16, 0x15
OUT TCNT1H, R16 ;store 0x15 in TEMP of Timer1
does not work properly. This is because, when the TCNT1L is loaded, the content
of TEMP will be loaded into TCNT1H. But when the TCNT1L register is loaded,
TEMP contains garbage (improper data), and this is not what we want.
• When we read the low byte of 16-bit registers, the content of the high byte will
be copied to the TEMP register. So, the following program reads the content of
TCNT1:
IN R20,TCNT1L ; R20 = TCNT1L, TEMP = TCNT1H
IN R21,TCNT1H ; R21 = TEMP of Timer1
• We must pay attention to the order of reading the high and low bytes of the 16-
bit registers. Otherwise, the result is erroneous.
97
Accessing 16-bit registers (5/5)
98
99
Example 9-30 (2/3)
100
Example 9-30 (3/3)
101
102
Example 9-31 (2/2)
103
Generating a large time delay using prescaler
105
CSOO, CS01, and CS02 bits in the TCCRO register
106
8-bit up counter
107
16-bit up counter
108
109
110
Example 9-38 (2/2)
111
Outline
1. Overview of Timers in ATmega32
2. Programming Timers 0, 1, and 2
– Programming 8-bit Timers: Timers 0 and 2
• 8-bit timer
• Normal Mode
• CTC mode
– Programming 16-bit Timer: Timer 1
3. Counter Programming
4. Programming Timers in C
112
• In Chapter 7 we showed some examples of C programming
for the AVR.
• In this section we show C programming for the AVR timers.
As we saw in the examples in Chapter 7, the general-
purpose registers of the AVR are under the control of the C
compiler and are not accessed directly by C statements.
• All of the SFRs (Special Function Registers), however, are
accessible directly using C statements.
• As an example of accessing the SFRs directly, we saw how
to access ports PORTB-PORTD in Chapter 7.
• In C we can access timer registers such as TCNT0, OCR0,
and TCCR0 directly using their names. See Example 9-39.
113
114
Calculating delay length using timers
• As we saw in the last two sections, the delay length
depends primarily on two factors: (a) the crystal frequency,
and (b) the prescaler factor. A third factor in the delay size
is the C compiler because various C compilers generate
different hex code sizes, and the amount of overhead due to
the instructions varies by compiler.
115
116
117
Example 9-41 (2/2)
118
119
Example 9-42 (2/2)
120
C programming of Timers 0 and 1 as counters
• In Section 9.2 we showed how to use Timers 0 and 1 as
event counters.
121
122
123
Summary
• The AVR has one to six timers/counters depending on the family
member. When used as timers, they can generate time delays.
When used as counters, they can serve as event counters.
• Some of the AVR timers are 8-bit and some are 16-bit. The 8-bit
timers are accessed as TCNTn (like TCNT0 for Timer0), whereas
16-bit timers are accessed as two 8-bit registers (TCNTnH,
TCNTnL).
• Each timer has its own TCCR (Timer/Counter Control Register)
register, allowing us to choose various operational modes. Among
the modes are the prescaler and timer/counter options. When the
timer is used as a timer, the AVR crystal is used as the source of
the frequency; however, when it is used as a counter, it is a pulse
outside of the AVR that increments the TCNT register.
• This chapter showed how to program the timers/counters to
generate delays and count events using Normal and CTC modes.
124