第 6章 MCS-51的定时器 /计数器两个可编程的定时器 /计数器 T1,T0。
两种工作模式:
( 1)计数器工作模式
( 2)定时器工作模式
4种工作方式 (方式 0-方式 3)。
6.1 定时器 /计数器的结构
TMOD,选择定时器 /计数器 T0,T1的工作模式和工作方式。
TCON,控制 T0,T1的启动和停止计数,同时包含了
T0,T1的状态。
单片机复位时,两个寄存器的所有位都被清 0。
6.1.1 工作方式控制寄存器 TMOD
8位分为两组,高 4位控制 T1,低 4位控制 T0。
( 1) GATE——门控位
0,以 TRX( X=0,1) 来启动定时器 /计数器运行。
1,用外中断引脚 (INT0*或 INT1*)上的高电平和 TRX
来启动定时器 /计数器运行 。
( 2) M1,M0——工作方式选择位
M1 M0 工 作 方 式
0 0 方式 0,13位定时器 /计数器 。
0 1 方式 1,16位定时器 /计数器 。
1 0 方式 2,8位常数自动重新装载
1 1 方式 3,仅适用于 T0,T0分成两个 8
位计数器,T1停止计数 。
(3) C/T*——计数器模式和定时器模式选择位
0,定时器模式 。
1,计数器模式 。
6.1.2 定时器 /计数器控制寄存器 TCON
低 4位与外部中断有关,已介绍。高 4位的功能如下:
(1) TF1,TF0——计数溢出标志位
(2) TR1,TR0——计数运行控制位
1,启动定时器 /计数器工作
0,停止定时器 /计数器工作
6.2 定时器 /计数器的 4种工作方式
6.2.1 方式 0
M1,M0为 00,定时器 /计数器的框图:
为 13位的计数器,C/T* 位决定工作模式:
0,开关打在上面,为定时器工作模式;
1,开关打在下面,为计数器工作模式,计数脉冲为 P3.4,P3.5引脚上的外部输入脉冲,当引脚上发生负跳变时,计数器加 1。
GATE位:决定定时器 /计数器的运行取决于 TRX一个条件还是 TRX和 INTX*引脚两个条件 。
( 1) 0,A点 ( 见图 6-2) 是否计数,仅取决于 TRX的状态 。
( 2) 1,B点电位由 INTX*的输入电平和 TRX的状态这两个条件来确定 。 是否计数是由 TRX和 INTX*二个条件来控制的 。
6.2.2 方式 1
M1,M0=01,16位 的计数器。
6.2.3 方式 2
计数满后自动装入计数初值 。
M1,M0=10,等效框图如下:
TLX作为常数缓冲器,当 TLX计数溢出时,在置,1”
溢出标志 TFX的同时,还 自动的将 THX中的初值送至
TLX,使 TLX从初值开始重新计数 。 定时器 /计数器的方式 2工作过程如图 6-5(X=0,1)。
省去用户软件中重装初值的程序,精确的定时。
6.2.4 方式 3
增加一个 附加 的 8位定时器 /计数器,从而具有 3个定时器 /计数器。
只适用于定时器 /计数器 T0。 T1不能工作在方式 3,
T1方式 3时相当于 TR1=0,停止计数(此时 T1可用来作串行口波特率产生器)。
1.工作方式 3下的 T0
T0分为两个独立的 8位计数器,TL0和 TH0 。 TL0使用
T0的状态控制位 C/T*,GATE,TR0、,而 TH0被固定为一个 8位定时器(不能作外部计数模式),并使用定时器 T1的状态控制位 TR1和 TF1,同时占用定时器 T1的中断请求源 TF1。
各引脚与 T0的逻辑关系如图所示:
2,T0工作在方式 3下 T1的各种工作方式当 T1用作串行口的波特率发生器时,T0才工作在方式 3。 T0处于方式 3时,T1可定为方式 0、方式 1和方式 2,用来作为串行口的波特率发生器,或不需要中断的场合。
( 1) T1工作在方式 0
( 2) T1工作在方式 1
( 3) T1工作在方式 2
6.3 定时器 /计数器对输入信号的要求外部计数脉冲的最高频率为系统振荡器频率的 1/24,
例如选用 12MHz频率的晶体,则可输入 500KHz的外部脉冲。
输入信号的高、低电平至少要保持一个机器周期。
如图 6-10所示,图中 Tcy为机器周期。
6.4 定时器 /计数器的编程和应用
4种工作方式中,方式 0与方式 1基本相同,由于方式 0
是为兼容 MCS-48而设,初值计算复杂,在实际应用中,一般不用方式 0,而采用方式 1。
6.4.1 方式 1应用例 6-1 假设系统时钟频率采用 6MHz,要在 P1.0上输出一个周期为 2ms的方波,如图所示。
方波的周期用 T0来确定,让 T0每隔 1ms计数溢出 1次,
既 T0每隔 1ms产生一次中断,CPU相应中断后,在中断服务程序中对 P1.0取反。
(1)计算初值 X
设初值为 X,则有,
(216-X)× 2× 10-6=1× 10-3
216-X=500 X=65036
X化为 16进制,即 X=FE0CH=1111111000001100B。
所以,T0的初值为:
TH0=0FEH TL0=0CH
(2)初始化程序设计主要是对寄存器 IP,IE,TCON,TMOD的相应位进行正确设置,将计数初值送入定时器中。
(3)程序设计中断服务程序除了完成要求的产生方波这一工作之外,
还要注意将计数初值重新装入定时器中,为下一次产生中断作准备。
参考程序:
ORG 0000H
RESET,AJMP MAIN ; 转主程序
ORG 000BH ; T0的中断入口
AJMP IT0P ; 转 T0中断处理程序 IT0P
ORG 0100H
MAIN,MOV SP,#60H ; 设堆栈指针
MOV TMOD,#01H ; 设置 T0为方式 1
ACALL PT0M0 ; 调用子程序 PT0M0
HERE,AJMP HERE ; 自身跳转
PT0M0,MOV TL0,#0CH ; T0中断服务程序,T0重新置初值
MOV TH0,#0FEH
SETB TR0 ; 启动 T0
SETB ET0 ; 允许 T0中断
SETB EA ; CPU开中断
RET
ITOP,MOV TL0,#0CH ; T0中断服务子程序,T0置初值
MOV TH0,#0FEH
CPL P1.0 ; P1.0的状态取反
RETI
查询方式的参考程序,
MOV TMOD,#01H ; 设置 T0为方式 1
SETB TR0 ; 接通 T0
LOOP,MOV TH0,#0FEH ; T0置初值
MOV TL0,# 0CH
LOOP1,JNB TF0,LOOP1 ; 查询 TF0标志
CLR TR0 ; T0溢出,关闭 T0
CPL P1.0 ; P1.0的状态求反
SJMP LOOP
例 6-2 假设 系统时钟为 6MHz,编写定时器 T0产生 1秒定时的程序 。
( 1) T0工作方式的确定因定时时间较长,采用哪一种工作方式?
由各种工作方式的特性,可计算出:
方式 0最长可定时 16.384ms;
方式 1最长可定时 131.072ms;
方式 2最长可定时 512?s。
选方式 1,每隔 100ms中断一次,中断 10次为 1s。
( 2) 计算计数初值因为,(216-X)× 2× 10-6 = 10-1
所以,X=15536=3CB0H
因此,TH0=3CH,TL0=B0H
( 3) 10次计数的实现对于中断 10次计数,可使 T0工作在计数方式,也可用循环程序的方法实现。本例采用循环程序法。
( 4)程序设计参考程序,
ORG 0000H
RESET,LJMP MAIN ; 上电,转主程序入口 MAIN
ORG 000BH ; T0的中断入口
LJMP IT0P ; 转 T0中断处理程序 IT0P
ORG 1000H
MAIN,MOV SP,#60H ; 设堆栈指针
MOV B,#0AH ; 设循环次数 10次
MOV TMOD,#01H ; 设 T0工作在方式 1
MOV TL0,#0B0H ; 给 T0设初值
MOV TH0,#3CH
SETB TR0 ; 启动 T0
SETB ET0 ; 允许 T0中断
SETB EA ; CPU开放中断
HERE,SJMP HERE ; 等待中断
ITOP,MOV TL0,#0B0H ; T0中断子程序,重装初值
MOV TH0,#3CH ;
DJNZ B,LOOP
CLR TR0 ; 1s定时时间到,停止 T0工作
LOOP,RETI
6.4.2 方式 2的应用省去程序中重装初值的指令,并可产生相当精确的定时时间 。
例 6-3 当 T0( P3.4) 引脚上发生负跳变时,从 P1.0引脚上输出一个周期为 1ms的方波,如图所示 。 ( 系统时钟为 6MHz)
( 1) 工作方式选择
T0为方式 1计数,初值 0FFFFH,即外部计数输入端 T0
( P3.4) 发生一次负跳变时,T0加 1且溢出,溢出标志 TF0置,1”,发中断请求。在进入 T0中断程序后,
把 F0标志置,1”,说明 T0引脚上已接收了负跳变信号。 T1定义为方式 2定时。在 T0引脚产生一次负跳变后,
启动 T1每 500?s产生一次中断,在中断服务程序中对
P1.0求反,使 P1.0产生周期 1ms的方波。
( 2) 计算 T1初值设 T1的初值为 X:
则 (28-X)× 2× 10-6=5× 10-4
X=28-250=6=06H
( 3) 程序设计
ORG 0000H
RESET,LJMP MAIN ; 复位入口转主程序
ORG 000BH
JMP IT0P ; 转 T0中断服务程序
ORG 001BH
LJMP IT1P ; 转 T1中断服务程序
ORG 0100H
MAIN,MOV SP,#60H
ACALL PT0M2 ; 调用对 T0,T1初始化子程序
LOOP,MOV C,F0 ; T0产生过中断了吗,产生过中断,则 F0=1
JNC LOOP ; T0没有产生过中断,则跳到
LOOP,等待 T0中断
SETB TR1 ; 启动 T1
SETB ET1 ; 允许 T1中断
HERE,AJMP HERE
PT0M2,MOV TMOD,#26H ; 初始化,T1为方式 2定时,T0为方式 1计数
MOV TL0,#0FFH ; T0置初值
MOV TH0,#0FFH
SETB TR0 ; 启动 T0
SETB ET0 ; 允许 T0中断
MOV TL1,#06H ; T1置初值
MOV TH1,#06H
CLR F0 ; 把 T0已发生中断标志 F0清 0
SETB EA
RET
IT0P,CLR TR0 ; T0中断服务程序,停止 T0计数
SETB F0 ; 建立产生中断标志
RETI
IT1P,CPL P1.0 ; T1中断服务,P1.0位取反
RETI
在 T1定时中断服务程序 IT1P中,省去了 T1中断服务程序中重新装入初值 06H的指令。
例 6-4 利用 T1的方式 2对外部信号计数,要求每计满
100个数,将 P1.0取反。
本例是 方式 2计数模式 的应用。
( 1)选择工作方式外部信号由 T1(P3.5) 脚输入,每发生一次负跳变计数器加 1,每输入 100个脉冲,计数器产生溢出中断,
在中断服务程序中将 P1.0取反一次。
T1 方式 2的控制字为 TMOD=60H。 不使用 T0时,TMOD的低 4位可任取,但不能使 T0进入方式 3,这里取全 0。
( 2) 计算 T1的初值
X=28-100=156=9CH
因此,TL1的初值为 9CH,重装初值寄存器 TH1=9CH
( 3) 程序设计
ORG 0000H
LJMP MAIN
ORG 001BH; T1中断服务程序入口
CPL P1.0 ; P1.0位取反
RETI
ORG 0100H
MAIN,MOV TMOD,#60H ; 设 T1为方式 2计数
MOV TL0,#9CH ; T0置初值
MOV TH0,#9CH
SETB TR1 ; 启动 T1
HERE,AJMP HERE
6.4.3 方式 3的应用
T0 方式 3时,TL0和 TH0被分成两个独立的 8位定时器 /
计数器。其中,TL0,8位定时器 /计数器;
TH0,8位定时器。
当 T1作串行口波特率发生器时,T0才设置为方式 3。
例 6-5 假设某 MCS-51应用系统的两个外中断源已被占用,设置 T1工作在方式 2,作波特率发生器用。现要求增加一个外部中断源,并控制 P1.0引脚输出一个
5kHz的方波。设系统时钟为 6MHz。
( 1) 选择工作方式
TL0为方式 3计数,把 T0引脚 ( P3.4) 作附加的外中断输入端,TL0初值设为 0FFH,当检测到 T0引脚电平出现负跳变时,TL0溢出,申请中断,这相当于跳沿触发的外部中断源 。
TH0为 8位方式 3定时,控制 P1.0输出 5kHz的方波信号 。
如图所示 。
( 2) 初值计算
TL0的初值设为 0FFH。
5kHz的方波的周期为 200?s,TH0的定时时间为 100?s。
TH0初值 X计算如下:
(28-X)× 2× 10-6=1× 10-4
X=28-100=156=9CH
( 3) 程序设计
ORG 0000H
LJMP MAIN
ORG 000BH ; T0中断入口
LJMP TL0INT; 跳 T0中断服务程序
ORG 001BH ; 在 T1方式 3时,TH0占用 T1的中断
LJMP TH0INT; 跳 TH0中断服务程序
ORG 0100H
MAIN,MOV TMOD,#27H ; T0方式 3计数,T1方式 2定时
MOV TL0,#0FFH ; 置 TL0初值
MOV TH0,#9CH ;置 TH0初值
MOV TL1,#dataL ; data为波特率常数
MOV TH1,#dataH
MOV TCON,#55H ; 允许 T0中断
MOV IE,#9FH ; 启动 T1

TL0INT,MOV TL0,#0FFH ; TL0中断服务程序,
TL0重新装入初值中断处理
TH0INT,MOV TH0,#9CH ; TH0中断服务程序,TH0重新装入初值
CPL P1.0 ; P1.0位取反输出
RETI
6.4.4 门控制位 GATE的应用 —测量脉冲宽度
GATE1可使定时器 /计数器 T1的启动计数受 INT1*的控制,
可测量引脚 INT1*( P3.3) 上正脉冲的宽度 (机器周期数)。
参考程序:
ORG 0000H
RESET,AJMP MAIN ; 复位入口转主程序
ORG 0100H
MAIN,MOV SP,#60H
MOV TMOD,#90H ; T1为方式 1定时控制字
MOV TL1,#00H
MOV TH1,#00H
LOOP,JB P3.3,LOOP0 ; 等待 INT1*低
SETB TR1 ; 如 INT1*为低,启动 T1
LOOP1,JNB P3.3,LOOP1 ; 等待 INT1*升高
LOOP2,JB P3.3,LOOP2 ; 等待 INT1*降低
CLR TR1 ; 停止 T1计数
MOV A,TL1 ; T1计数值送 A
将 A中的 T1计数值送显示缓冲区转换成显示的代码
LOOP3,LCALL DIR ; 调用显示子程序 DIR; 显示 T1计数值
AJMP LOOP3 ;
执行程序,使 INT1*引脚上出现的 正脉冲宽度以机器周期数的形式显示在显示器上 。
6.4.5 实时时钟的设计
1,实时时钟实现的基本思想如何获得 1秒的定时,可把定时时间定为 100ms,采用中断方式进行溢出次数的累计,计满 10次,即得到秒计时。
片内 RAM中规定 3个单元作为秒、分、时单元,具体安排如下:
42H:,秒,单元 ; 41H:,分,单元; 40H:,时,
单元从秒到分,从分到时是通过软件累加并进行比较的方法来实现的。
2.程序设计
( 1)主程序的设计流程如图所示。
( 2)中断服务程序的设计中断服务程序的主要功能是实现秒、分、时的计时处理。参考程序略。
6.4.6 运行中读定时器 /计数器在读取运行中的定时器 /计数器时,需注意:若恰好出现 TLX溢出向 THX进位的情况,则读得的 ( TLX) 值就完全不对 。 同样,先读 ( THX) 再读 ( TLX) 也可能出错 。
方法:先读( THX),后读( TLX),再读( THX)。 若两次读得( THX) 相同,则读的内容正确。 若前后两次读的( THX) 有变化,则再重复上述过程,这次重复读得的内容就应是正确的。下面是有关的程序,
读得的( TH0) 和( TL0) 放置在 R1和 R0内。
RDTIME:MOV A,TH0 ; 读 ( TH0)
MOV R0,TL0 ; 读 ( TL0)
CJNE A,TH0,RDTIME; 比较 2次读得的 ( TH0);不相等则重复读
MOV R1,A ; ( TH0) 送入 R1中
RET