Principle and Interface Techniques of Microcontroller: - 8051 Microcontroller and Embedded Systems Using Assembly and C
Principle and Interface Techniques of Microcontroller: - 8051 Microcontroller and Embedded Systems Using Assembly and C
Techniques of Microcontroller
--8051 Microcontroller and Embedded Systems
Using Assembly and C
杭州 • 浙江大学 • 2014
Chapter 10
Timer Programming
Outline
§10-1 Programming Timer
MOV TL0,#4FH
MOV R5,TH0
TMOD Register
Both timers 0 and 1 use the same register,
called TMOD (timer mode), to set the
various timer operation modes TMOD is a 8-
bit register
The lower 4 bits are for Timer 0
The upper 4 bits are for Timer 1
In each case,
The lower 2 bits are used to set the timer mode
The upper 2 bits to specify the operation
TMOD Register
Example 10-2
Find the timer’s clock frequency and its period for various 8051-based
system, with the crystal frequency 11.0592 MHz when C/T bit of TMOD is 0.
Solution:
If C/T = 0, it is used as a
XTAL
÷12 timer for time delay
oscillator
generation.
1/12 × 11.0529 MHz = 921.6 MHz; The clock source for the
T = 1/921.6 kHz = 1.085 us time delay is the crystal
frequency of the 8051
TMOD Register
Timers of 8051 do starting and stopping by either software
or hardware control
In using software to start and stop the timer where GATE=0
The start and stop of the timer are controlled by way of software by
the TR (timer start) bits TR0 and TR1
– The SETB instruction starts it, and it is stopped by the CLR
instruction
• Timer 0, mode 2
– These instructions start and stop the timers as long as GATE=0 in the
• C/T = 0 to use XTAL
TMOD register
clock source
The hardware way of starting and stopping the timer • gateby
= 0antoexternal
use
source is achieved by making GATE=1 in the TMOD register
internal (software)
start and stop method.
Find the value for TMOD if we want to program timer 0 in mode 2, use
8051 XTAL for the clock source, and use instructions to start and stop the
timer.
TMOD = 0000 0010
Mode 0
13-bit timer mode
8-bit timer/counter THx with TLx as 5-bit
prescaler
Mode 1 Programming
The following are the characteristics and
operations of mode1:
1. It is a 16-bit timer; therefore, it allows value of 0000 to
FFFFH to be loaded into the timer’s register TL and TH
2. After TH and TL are loaded with a 16-bit initial value, the
timer must be started
This is done by SETB TR0 for timer 0 and SETB TR1 for timer 1
3. After the timer is started, it starts to count up
It counts up until it reaches its limit of FFFFH
Mode 1 Programming
When it rolls over from FFFFH to 0000, it sets high a flag bit called
TF (timer flag)
– Each timer has its own timer flag: TF0 for timer 0, and TF1 for
timer 1
– This timer flag can be monitored
When this timer flag is raised, one option would be to stop the
timer with the instructions CLR TR0 or CLR TR1, for timer 0 and
timer 1, respectively
4. After the timer reaches its limit and rolls over, in order to
repeat the process
TH and TL must be reloaded with the original value, and TF must
be reloaded to 0
Steps to Mode 1 Program
To generate a time delay
1. Load the TMOD value register indicating which timer
(timer 0 or timer 1) is to be used and which timer mode (0
or 1) is selected
2. Load registers TL and TH with initial count value
3. Start the timer
4. Keep monitoring the timer flag (TF) with the JNB TFx,
target instruction to see if it is raised
Get out of the loop when TF becomes high
5. Stop the timer
6. Clear the TF flag for the next round
7. Go back to Step 2 to load TH and TL again
Example 10-3
In the following program, we create a square wave of 50% duty cycle
(with equal portions high and low) on the P1.5 bit. Timer 0 is used to
generate the time delay. Analyze the program
(a) in hex(FFFF – YYXX + 1) ×1.085 us, (b) in decimal Convert YYXX values
where YYXX are TH, TL initial values of the TH, TL register to decimal to
respectively. get a NNNNN decimal, then
Notice that value YYXX are in hex. (65536 - NNNN) ×1.085 us
Example 10-5
In Example 10-4, calculate the frequency of the square wave
generated on pin P1.5.
Solution:
In the timer delay calculation of Example 9-5, we did not include the
overhead due to instruction in the loop. To get a more accurate timing, we
need to add clock cycles due to this instructions in the loop. To do that, we
use the machine cycle from Table A-1 in Appendix A, as shown below.
Cycles
HERE: MOV TL0,#0F2H 2
MOV TH0,#0FFH 2
CPL P1.5 1
ACALL DELAY 2
SJMP HERE 2
DELAY:
SETB TR0 1
AGAIN: JNB TF0,AGAIN 14
CLR TR0 1
CLR TF0 1
RET 2
Total 28
T = 2 × 28 × 1.085 us = 60.76 us and F = 16458.2 Hz
Example 10-6
Find the delay generated by timer 0 in the following code, using both of the
Methods of Figure 9-4. Do not include the overhead due to instruction.
CLR P2.3 ;Clear P2.3
MOV TMOD,#01 ;Timer 0, 16-bitmode
HERE: MOV TL0,#3EH ;TL0=3Eh, the low byte
MOV TH0,#0B8H ;TH0=B8H, the high byte
SETB P2.3 ;SET high timer 0
SETB TR0 ;Start the timer 0
AGAIN: JNB TF0,AGAIN ;Monitor timer flag 0
CLR TR0 ;Stop the timer 0
CLR TF0 ;Clear TF0 for next round
CLR P2.3
Solution:
(a) (FFFFH – B83E + 1) = 47C2H = 18370 in decimal and
18370 ×1.085 us = 19.93145 ms
(b) Since TH – TL = B83EH = 47166 (in decimal) we have
65536 –47166 = 18370. This means that the timer counts from B38EH to
FFFF. This plus Rolling over to 0 goes through a total of 18370 clock cycles,
where each clock is 1.085 us in duration. Therefore, we have 18370 × 1.085
us = 19.93145 ms as the width of the pulse.
Example 10-7
Modify TL and TH in Example 10-6 to get the largest time delay possible. Find
the delay in ms. In your calculation, exclude the overhead due to the
instructions in the loop.
Solution:
To get the largest delay we make TL and TH both 0. This will count up from
0000 to FFFFH and then roll over to zero.
CLR P2.3 ;Clear P2.3
MOV TMOD,#01 ;Timer 0, 16-bitmode
HERE: MOV TL0,#0 ;TL0=0, the low byte
MOV TH0,#0 ;TH0=0, the high byte
SETB P2.3 ;SET high P2.3
SETB TR0 ;Start timer 0
AGAIN: JNB TF0,AGAIN ;Monitor timer flag 0
CLR TR0 ;Stop the timer 0
CLR TF0 ;Clear timer 0 flag
CLR P2.3
Making TH and TL both zero means that the timer will count from 0000 to
FFFF, and then roll over to raise the TF flag. As a result, it goes through a
total Of 65536 states. Therefore, we have delay =(65536 - 0)×1.085 us =
71.1065ms.
Example 10-8
The following program generates a square wave on P1.5 continuously using
timer 1 for a time delay. Find the frequency of the square wave if XTAL =
11.0592 MHz. In your calculation do not include the overhead due to
instructions in the loop.
MOV TMOD,#10 ;Timer 1, mod 1 (16-bitmode)
AGAIN: MOV TL1,#34H ;TL1=34H, low byte of timer
MOV TH1,#76H ;TH1=76H, high byte timer
SETB TR1 ;start the timer 1
BACK: JNB TF1,BACK ;till timer rolls over
CLR TR1 ;stop the timer 1
CPL P1.5 ;comp. p1. to get hi, lo
CLR TF1 ;clear timer flag 1
SJMP AGAIN ;is not auto-reload
Solution:
Since FFFFH – 7634H = 89CBH + 1 = 89CCH and 89CCH = 35276
clock count and 35276 × 1.085 us = 38.274 ms for half of the square wave.
The frequency = 13.064Hz.
Also notice that the high portion and low portion of the square wave pulse are
equal. In the above calculation, the overhead due to all the instruction in the
loop is not included.
Finding the Loaded Timer Values
To calculate the values to be loaded into the TL
and TH registers, look at the following example
Assume XTAL = 11.0592 MHz, we can use the following
steps for finding the TH, TL registers’ values
1. Divide the desired time delay by 1.085 us
2. Perform 65536 – n, where n is the decimal value we got
in Step1
3. Convert the result of Step2 to hex, where yyxx is the
initial hex value to be loaded into the timer’s register
4. Set TL = xx and TH = yy
Example 10-9
Assume that XTAL = 11.0592MHz. What value do we need to load the
timer’s register if we want to have a time delay of 5 ms (milliseconds)?
Show the program for timer 0 to create a pulse width of 5 ms on P2.3.
Solution:
Since XTAL = 11.0592 MHz, the counter counts up every 1.085 us. This
means that out of many 1.085 us intervals we must make a 5 ms pulse. To
get that, we divide one by the other. We need 5 ms / 1.085 us = 4608
clocks. To Achieve that we need to load into TL and TH the value 65536 –
4608 = EE00H. Therefore, we have TH = EE and TL = 00.
CLR P2.3 ;Clear P2.3
MOV TMOD,#01 ;Timer 0, 16-bitmode
HERE: MOV TL0,#0 ;TL0=0, the low byte
MOV TH0,#0EEH ;TH0=EE, the high byte
SETB P2.3 ;SET high P2.3
SETB TR0 ;Start timer 0
AGAIN: JNB TF0,AGAIN ;Monitor timer flag 0
CLR TR0 ;Stop the timer 0
CLR TF0 ;Clear timer 0 flag
Example 10-10
Assume that XTAL = 11.0592 MHz, write a program to generate a square
wave of 2 kHz frequency on pin P1.5.
Solution:
This is similar to Example10-9, except that we must toggle the bit to generate
the square wave. Look at the following steps.
(a) T = 1 / f = 1 / 2 kHz = 500 us the period of square wave.
(b) 1 / 2 of it for the high and low portion of the pulse is 250 us.
(c) 250 us / 1.085 us = 230 and 65536 – 230 = 65306 which in hex is FF1AH.
(d) TL = 1A and TH = FF, all in hex. The program is as follow.
MOV TMOD,#01 ;Timer 0, 16-bitmode
AGAIN: MOV TL1,#1AH ;TL1=1A, low byte of timer
MOV TH1,#0FFH ;TH1=FF, the high byte
SETB TR1 ;Start timer 1
BACK: JNB TF1,BACK ;until timer rolls over
CLR TR1 ;Stop the timer 1
CLR P1.5 ;Clear timer flag 1
CLR TF1 ;Clear timer 1 flag
SJMP AGAIN ;Reload timer
Example 10-11
Assume XTAL = 11.0592 MHz, write a program to generate a square wave of
50 kHz frequency on pin P2.3.
Solution:
Look at the following steps.
(a) T = 1 / 50 = 20 ms, the period of square wave.
(b) 1 / 2 of it for the high and low portion of the pulse is 10ms.
(c) 10 ms / 1.085 us = 9216 and 65536 – 9216 = 56320 in decimal, and in
hex it is DC00H.
(d) TL = 00 and TH = DC (hex).
Solution:
First notice the target address of SJMP. In mode 2 we do not need to reload
TH since it is auto-reload. Now (256 - 05)×1.085 us = 251×1.085 us =
272.33us is the high portion of the pulse. Since it is a 50% duty cycle square
wave, the period T is twice that; as a result T = 2×272.33 us = 544.67us and
the frequency = 1.83597 kHz
Example 10-14
Find the frequency of a square wave generated on pin P1.0.
Solution:
MOV TMOD,#2H ;Timer 0, mod 2 (8-bit, auto reload)
MOV TH0,#0
AGAIN: MOV R5,#250 ;multiple delay count
ACALL DELAY
CPL P1.0
SJMP AGAIN
DELAY: SETB TR0 ;start the timer 0
BACK: JNB TF0,BACK ;stay timer rolls over
CLR TR0 ;stop timer
CLR TF0 ;clear TF for next round
DJNZ R5,DELAY
RET
The upper four bits are used The lower 4 bits are set
to store the TF and TR bits aside for controlling the
of both timer 0 and 1 interrupt bits
TCON Register
TCON register is a bit-addressable register
Equivalent instruction for the Timer Control Register
TCON Register
Case of GATE = 1
If GATE = 1, the start and stop of the timer
are done externally through pins P3.2 and
P3.3 for timers 0 and 1, respectively
This hardware way allows to start or stop the
timer externally at any time via a simple switch
§10-3 Programming Timers in C
Accessing Timer Registers
Example 10-17
Write an 8051 C program to toggle all the bits of port P1 continuously
with some delay in between. Use Timer 0, 16-bit mode to generate the
delay.
Solution:
FFFFH – 3500H = CAFFH
#include <reg51.h>
= 51967 + 1 = 51968
void T0Delay(void); void T0Delay(){
51968×1.085μs = 56.384ms
void main(void){ TMOD=0x01;
is the approximate delay
while (1) { TL0=0x00;
P1=0x55; TH0=0x35;
T0Delay(); TR0=1;
P1=0xAA; while (TF0==0);
T0Delay(); TR0=0;
} TF0=0;
} }
Calculating Delay Length Using Timers
To speed up the 8051, many recent versions of the
8051 have reduced the number of clocks per
machine cycle from 12 to four, or even one
#include <reg51.h>
void T0M1Delay(void); void T0M1Delay(void) FFFFH – 4BFDH = B402H
sbit mybit=P1^5; { = 46082 + 1 = 46083
void main(void) TMOD=0x01; 46083×1.085 μs = 50ms
{ TL0=0xFD;
while (1) TH0=0x4B;
{ TR0=1;
mybit=~mybit; while (TF0==0);
T0M1Delay(); TR0=0;
} TF0=0;
} }
Times 0/1 Delay Using Mode 1
(16-bit Non Auto-reload)
Example 10-19
Write an 8051 C program to toggle all bits of P2 continuously every 500ms.
Use Timer 1, mode 1 to create the delay.
Solution:
//tested for DS89C420, XTAL = 11.0592 MHz
#include <reg51.h>
void T1M1Delay(void); A5FEH = 42494 in decimal
void main(void) void T1M1Delay(void) 65536 – 42494 = 23042
{ { 23042×1.085μs = 25ms and
unsigned char x; TMOD=0x10; 20×25ms = 500ms
P2=0x55; TL1=0xFE;
while (1) TH1=0xA5;
{ TR1=1;
P2=~P2; while (TF1==0);
for (x=0;x<20;x++) TR1=0;
T1M1Delay(); TF1=0;
} }
}
Times 0/1 Delay Using Mode 1
(16-bit Non Auto-reload)
Example 10-20
A switch is connected to pin P1.2. Write an 8051 C program to monitor SW
and create the following frequencies on pin P1.7: FC67H = 64615
SW=0: 500Hz 65536 – 64615 = 921
SW=1: 750Hz, use Timer 0, mode 1 for both of them. 921×1.085 μs = 999.285μs
Solution: 1 / (999.285μs×2) = 500Hz
#include <reg51.h> void T0M1Delay(unsigned char c){
sbit mybit=P1^5; TMOD=0x01;
sbit SW=P1^7; if (c==0) {
void T0M1Delay(unsigned char); TL0=0x67;
void main(void){ TH0=0xFC;
SW=1; }
while (1) { else {
mybit=~mybit; TL0=0x9A;
if (SW==0) TH0=0xFD;
T0M1Delay(0); }
else TR0=1;
T0M1Delay(1); while (TF0==0);
} TR0=0;
} TF0=0;
}
Times 0/1 Delay Using Mode 2
(8-bit Auto-reload)
Example 10-21
Write an 8051 C program to toggle only pin P1.5 continuously every 250ms.
Use Timer 0, mode 2 (8-bit auto-reload) to create the delay.
Solution:
#include <reg51.h>
void T0M2Delay(void); void T0M2Delay(void){
sbit mybit=P1^5; TMOD=0x02;
void main(void){ TH0=-23;
unsigned char x,y; TR0=1;
while (1) { while (TF0==0);
mybit=~mybit; TR0=0;
for (x=0;x<250;x++) TF0=0;
for (y=0;y<36;y++) //we put 36, not 40 }
T0M2Delay();
}
}
256 – 23 = 233
Due to overhead of the for loop in 23×1.085μs = 25μs and
C, we put 36 instead of 40 25μs×250×40 = 250ms
Example 10-22
Write an 8051 C program to create a frequency of 2500 Hz on pin P2.7. Use
Timer 1, mode 2 to create delay.
Solution:
#include <reg51.h>
void T1M2Delay(void);
sbit mybit=P2^7;
void main(void){
unsigned char x;
while (1) {
mybit=~mybit;
T1M2Delay();
}
}
void T1M2Delay(void){ 1/2500Hz = 400μs
TMOD=0x20; 400μs /2 = 200μs
TH1=-184; 200 μs / 1.085μs = 184
TR1=1;
while (TF1==0);
TR1=0;
TF1=0;
}
C Programming of Timers as Counters
Example 10-23
Assume that a 1-Hz external clock is being fed into pin T1 (P3.5). Write a C
program for counter 1 in mode 2 (8-bit auto reload) to count up and display
the state of the TL1 count on P1. Start the count at 0H.
Solution:
#include <reg51.h>
sbit T1=P3^5;
void main(void){
T1=1;
TMOD=0x60;
TH1=0;
while (1) {
do {
TR1=1;
P1=TL1;
}
while (TF1==0);
TR1=0;
TF1=0;
}
}
Example 10-24
Assume that a 1-Hz external clock is being fed into pin T0 (P3.4). Write a C
program for counter 0 in mode 1 (16-bit) to count the pulses and display the
state of the TH0 and TL0 registers on P2 and P1,respectively.
Solution:
#include <reg51.h>
void main(void){
T0=1;
TMOD=0x05;
TL0=0
TH0=0;
while (1) {
do {
TR0=1;
P1=TL0;
P2=TH0;
}
while (TF0==0);
TR0=0;
TF0=0;
}
}
Discussion: What’s new in Timer
More Timer/Counter
More clock source
16 bits reload
PWM output automatically
Up/Down counter
Dynamic trigger level
Watch dog
实验:参考实验六、七、八
(详见实验讲义)
要求:
1. 编写程序,统计按键次数;
2. 在LED数码管上显示按键个数;
3. 支持长按键,即按键时间超过1
秒后,每0.2秒键值+1;