1、第6章 定时器/计数器及其应用 学习目标(1)掌握定时器/计数器的内部结构和工作原理(2)掌握定时器/计数器的工作方式和工作模式。(3)掌握定时器/计数器的编程应用。学习重点和难点(1)定时器/计数器的工作方式和工作模式(2)定时器/计数器的中断服务程序设计6.1 定时/计数器的结构及工作原理AT8951单片机片内有两个可编程的定时/计数器T1、T0,都有定时和计数的功能,可用于定时控制、延时、对外部事件计数和检测等场合。两个16位定时计数器都是16位加1计数器。其中T0由两个8位特殊功能寄存器TH0和TL0构成;T1由TH1和TL1构成。6.2 定时器/计数器的控制寄存器 6.2.1工作模式
2、寄存器TMOD TMOD用于控制T0和T1的工作模式,字节地址为89H,不可进行位寻址。TMOD寄存器的高4位控制T1,低4位控制T0。TMODD7D6D5D4D3D2D1D089HGATEC/M1M0GATEC/M1M0(1)GATE:门控位。0:仅由运行控制位TRx(x=0,1)来控制定时器/计数器运行。1:用外中断引脚上的电平与运行控制位TRx共同来控制定时器/计数器运行。(2)M1、M0:工作方式选择位 M1、M0共有4种编码,对应于4种工作方式的选择 M1 M0 工作方式 0 0 方式0,13位定时/计数器 0 1 方式1,16位定时/计数器 1 0 方式2,8位自动重装初值的定时/
3、计数器 1 1 方式3,仅适用于T0,此时分成两个8位计数器,T1停止计数(3)C/:计数器模式和定时器模式选择位 0:为定时器工作模式,对单片机的晶体振荡器12分频后的脉冲进行计数。1:为计数器工作模式,计数器对外部输入引脚T0(P3.4)或T1(P3.5)的外部脉冲(负跳变)计数。2.定时器/计数器控制寄存器TCON 字节地址为88H,可位寻址,位地址为88H8FH。TCOND7D6D5D4D3D2D1D088HTF1TR1TF0TR0IE1IT1IE0IT0(1)TF1、TF0计数溢出标志位。当计数器计数溢出时,该位置“1”。使用查询方式时,此位作为状态位供CPU查询,但应注意查询有效后
4、,应使用软件及时将该位清“0”。使用中断方式时,此位作为中断请求标志位,进入中断服务程序后由硬件自动清“0”。(2)TR1、TR0计数运行控制位。TR1位(或TR0位)=1,启动定时器/计数器工作的必要条件。TR1位(或TR0位)=0,停止定时器/计数器工作。该位可由软件置“1”或清“0”。5.5.3定时计数器的四种工作方式 1.方式0:当M1、M0=00时,被设置为工作方式0 2.方式1 当M1、M0=01时,定时器/计数器工作于方式1,这时定时器/计数器的等效电路逻辑结构如图5-9所示。3.方式2当M1、M0=10时,定时器/计数器工作于方式2。方式2把TL0或TH0设置成一个可以自动重装
5、初值的8位定时/计数器。TL1计数溢出时,不仅使溢出中断标志位TF1置1,而且还自动把TH1中的内容重新装载到TL1中。这里,16位定时/计数器被拆成两个,TL1用作8位计数器,TH1用来保存初值。在程序初始化时,TH1和TL1用程序赋予相同的值,当TL1计数溢出,使TF1置位为1,并将TH1中的初值自动装入TL1,继续计数。4.方式3:当M1、M0=11时,定时器/计数器工作于方式3。方式3是为增加一个8位定时器/计数器而设,使AT89S51单片机具有3个定时器/计数器。方式3只适用于T0。T1不能工作在方式3。T1处于方式3时相当于TR1=0,停止计数(此时T1可用来作为串行口波特率产生器
6、)。1工作方式3下的T0 TMOD的低2位为11时,T0的工作方式被选为方式3,定时器/计数器T0分为两个独立的8位计数器TL0和TH0,TL0使用T0的状态控制位C/、GATE、TR0、TF0,而TH0被固定为一个8位定时器(不能作为外部计数模式),并使用定时器T1的状态控制位TR1和TF1,同时占用定时器T1的中断请求源TF1。2T0工作在方式3时T1的各种工作方式 一般情况下,当T1用作串行口的波特率发生器时,T0才工作在方式3。T0处于工作方式3时,T1可定为方式0、方式1和方式2,用来作为串行口的波特率发生器,或不需要中断的场合。定时器T1无工作方式3,若将T1设置为方式3,就会使T
7、1立即停止计数,也就是保持住原有的计数值,作用相当于使TR1=0。但T1可工作于其他三种方式下。一般情况下,当定时器T1用作串行口波特率发生器时,定时器T0才设置为工作方式3。此时,常把定时器T1设置为方式2,用作波特率发生器。5.5.4定时/计数器的编程和应用初始化:对TMOD赋值,确定T0、T1的工作方式和工作模式。计算初值,并写入TH0、TL0或 TH1、TL1。中断方式时,要对IE赋值,开放中断。使TR0或TR1置位,启动定时/计数器。1.方式1应用【例5-3】假设系统时钟频率采用6MHz,在P1.0引脚上输出一个周期为2ms的方波,如图5-12所示。机器周期=2s=2 106s 设需
8、要装入T0的初值为X,则有(216X)2106=1 103,216X=500,X=65036。X化为十六进制数,即:65036=FE0CH。T0的初值为TH0=FEH,TL0=0CH。采用定时器中断方式工作。包括定时器初始化和中断系统初始化,主要是对寄存器IP、IE、TCON、TMOD的相应位进行正确的设置,并将计数初值送入定时器中。ORG 0000H ;程序入口 RESET:AJMP MAIN ;转主程序 ORG 000BH ;T0中断入口 AJMP IT0P;转T0中断处理程序IT0P ORG 0100H;主程序入口 MAIN:MOV SP,#60H;设堆栈指针 MOV TMOD,#01H
9、;设置T0为方式1定时 MOV TL0,#0CH;T0初始化,装初值的低8位 MOV TH0,#0FEH;装初值的高8位 SETB ET0;允许T0中断 SETB EA ;总中断允许 SETB TR0;启动T0 HERE:AJMP HERE ;原地循环,等待中断 IT0P:MOV TL0,#0CH;中断子程序,T0重装初值 MOV TH0,#0FEH CPL P1.0 ;P1.0的状态取反 RETI 查询方式参考程序:MOV TMOD,#01H;设置T0为方式1 LOOP:MOV TH0,#0FEH;T0置初值 MOV TL0,#0CH SETB TR0 ;接通T0 LOOP1:JNB TF0
10、,LOOP1 ;查TF0,TF0=0,T0未溢出;TF0=1,T0溢出,CLRTR0 ;T0溢出,关断T0 CPLP1.0 ;P1.0的状态求反 SJMP LOOP 查询程序虽简单,但CPU必须要不断查询TF0标志,工作效率低。【例5-4】系统时钟为6MHz,编写定时器T0产生1s定时的程序。基本思想:采用定时器模式。因定时时间较长,首先确定采用哪一种工作方式。时钟为6MHz的条件下,定时器各种工作方式最长可定时时间:方式0最长可定时16.384ms;方式1最长可定时131.072ms;方式2最长可定时512s。由上可见,可选方式1,每隔100ms中断一次,中断10次为1s。(1)计算计数初值
11、X 因为(216 X)2 106=101,所以X=15536=3CB0H。因此TH0=3CH,TL0=B0H。(2)10次计数的实现 对于中断10次的计数,采用B寄存器作为中断次数计数器。(3)程序设计 参考程序如下:ORG 0000H;程序运行入口 RESET:LJMP MAIN ;跳向主程序入口MAIN ORG 000BH ;T0的中断入口 LJMP IT0P;转T0中断处理子程序IT0P ORG 1000H;主程序入口 MAIN:MOV SP,#60H;设堆栈指针 MOV B,#0AH;设循环次数10次 MOVTMOD,#01H;设置T0工作在方式1定时 MOV TL0,#0B0H;给T
12、0设初值 MOV TH0,#3CH SETB ET0;允许T0中断 SETB EA ;总中断允许 SETB TR0;启动T0 HERE:SJMP HERE;原地循环,等待中断 IT0P:MOV TL0,#0B0H ;T0中断子程序,T0重装初值 MOV TH0,#3CH DJNZ B,RTURN;B中断次数计数,减1非0则中断返回 CLRTR0 ;1s定时时间到,停止T0工作 SETB F0;1s定时时间到标志F0置1 RTURN:RETI 程序说明:“SJMP HERE”指令实际是一段主程序。在这段主程序中再通过对F0标志的判定,可知1s定时是否到,再进行具体处理。2.方式2应用 方式2是一
13、个可以自动重新装载初值的8位定时/计数器,可以省去重复在程序中重新装载初值的指令。如果某个定时/计数器不使用时,可以将其扩展为一个负跳沿触发的外部中断源。【例5-5】当T0(P3.4)引脚上发生负跳变时,作为P1.0引脚产生方波的启动信号。开始从P1.0脚上输出一个周期为1ms的方波,T0设为方式1计数,初值为FFFFH。当外部计数输入端T0(P3.4)发生一次负跳变时,T0加1且溢出,溢出标志TF0置“1”,向CPU发出中断请求,此时T0相当于一个负跳沿触发的外部中断源。进入T0中断程序后,F0标志置“1”,说明T0引脚上已接收过负跳变信号。T1定义为方式2定时。在T0引脚产生一次负跳变后,
14、启动T1每500s产生一次中断,在中断服务子程序中对P1.0求反,使P1.0产生周期1ms的方波。由于省去重新装初值指令,所以可产生精确的定时时间。(1)计算T1的初值 设T1的初值为x,则(28 x)2 106=5 104 x=28 250=6=06H ORG 0000H;程序入口 RESET:LJMP MAIN ;跳向主程序MAIN ORG 000BH ;T0的中断入口 LJMP IT0P ;转T0中断服务程序 ORG 001BH ;T1的中断入口 LJMP IT1P ;转T1中断服务程序 ORG 0100H;主程序入口 MAIN:MOV SP,#60H;设堆栈指针 MOV TMOD,#2
15、6H;对T0,T1初始化,T0方式1计数,T1方式2定时 MOV TL0,#0FFH;T0置初值 MOV TH0,#0FFH SETB ET0 ;允许T0中断 MOV TL1,#06H;T1置初值 MOV TH1,#06H CLR F0;把T0已发生中断标志F0清0 SETB EA ;总中断允许 SETB TR0 ;启动T0 LOOP:JNC F0,LOOP;T0未产生中断,C=0,则跳到LOOP,等待T0中断 SETB ET1 ;允许T1产生定时中断 SETB TR1 ;启动T1 HERE:AJMP HERE IT0P:CLRTR0 ;T0中断服务程序,停止T0计数 SETBF0 ;把T0引
16、脚接收过负脉冲标志F0置1,即接收过负跳变 RETI IT1P:CPL P1.0 ;T1中断服务程序,P1.0位取反 RETI 程序说明:主程序中设置定时计数器T0来检测外部下降沿信号。检测到信号以后程序转入中断入口地址000BH,中断服务程序将F0置1,作为方波的启动信号,使用T1来输出方波。程序中F0位的作用为是否检测到外部脉冲信号的表示位。【例5-6】利用定时计数器T1的模式2对外部信号计数,要求每记满100次,将P1.0端取反。(1)模式选择 外部信号由T1(P3.5)引脚输入,每发生一次负跳变计数器加一,每输入100个脉冲,计数器溢出一次,中断服务程序将P1.0取反一次。T1工作于计
17、数模式的方式2,控制字为TMOD=60H。T0不用时,TMOD的低4位可以任意设置,但不能使T0进入方式3,一般取0。(2)初值计算 X=28-100=156=9CH 所以,TL1的初值为9CH。(3)参考程序 ORG 0000H LJMP MAIN ORG 001BH ;中断服务程序入口地址 CPL P1.0 ;p1.0取反 RETI MIAN:MOV TMOD,#60H ;设置T1为计数模式方式2 MOV TL1,#9CH ;装入初值 MOV TH1,#9CH ;装入初值 MOV IE,#88H ;开放T1中断 SETB TR1 ;打开定时器T1 HERE:SJMP HERE ;等待中断3
18、.方式3应用 【例5-7】假设某AT89S51单片机应用系统的两个外部中断源已被占用,设置T1工作在方式2,用作波特率发生器。现要求增加一个外部中断源,并控制P1.0引脚输出一个5kHz(周期为200s)的方波。设时钟为12MHz。(1)初值X计算 TL0的初值设为0FFH。5kHz方波的周期为200s,因此TH0的定时时间为100s。初值X计算:(28 X)1 106=1 104 X=28 100=156=9CH ORG 0000H LJMP MAIN ORG 000BH ;TL0中断入口,TL0使用T0的中断 LJMP TL0INT ;跳向TL0中断服务程序,TL0占用T0中断 ORG 0
19、01BH ;TH0中断入口,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 ;TL1装入串口波特率常数 MOV TH1,#datah;TH1装入串口波特率常数 MOV TCON,#15H;允许T0中断 MOVIE,#9FH ;设置中断允许,总中断允许,TH0、TL0中断允许 HERE:AJMP HERE ;循环等待 T
20、L0INT:MOV TL0,#0FFH;TL0中断服务处理子程序,TL0重新装入初值 SETB TR1 ;开始启动TH0定时 RETI TH0INT:MOV TH0,#9CH ;TH0中断服务程序,TH0重新装入初值 CPLP1.0 ;P1.0位取反输出 RETI 4.门控制位的应用 【例5-8】测量引脚上出现的正脉冲宽度。将T1设置为定时模式的方式1,且GATE=1,计数初值为0,将TR1置1.如图5-14所示,当引脚上出现高电平时,开始对机器周期计数,当引脚上信号变为低电平时,停止计数,然后读取定时计数器的值。ORG0000H RESET:AJMP MAIN ;复位入口转主程序 ORG 0
21、100H ;主程序入口 MAIN:MOV SP,#60H MOV TMOD,#90H;向TMOD写控制字,T1为方式1定时,GATE1=1 MOV TL1,#00H MOV TH1,#00H LOOP0:JB P3.3,LOOP0;等待INTO变低 SETB TR1 ;如INTO为低,启动T1 LOOP1:JNB P3.3,LOOP1 ;等待 升高 LOOP2:JB P3.3,LOOP2 ;INTO为高,此时计数器计数,等待降低 CLR TR1 ;停止T1计数 MOV A,TL1 ;T1计数值送A 5.实时时钟的设计 1实现实时时钟的基本思想 最小计时单位是秒,如何获得1s的定时时间呢?从前面
22、介绍知,定时器方式1,最大定时时间也只能131ms。可将定时器的定时时间定为100ms,中断方式进行溢出次数的累计,计满10次,即得秒计时。而计数10次可用循环程序的方法实现。初值的计算如例5-3。片内RAM规定3个单元为秒、分、时单元:42H:“秒”单元;41H:“分”单元;40H:“时”单元从秒到分,从分到时是通过软件累加并比较来实现。要求每满1秒,则“秒”单元42H中的内容加1;“秒”单元满60,则“分”单元41H中的内容加1;“分”单元满60,则“时”单元40H中的内容加1;“时”单元满24,则将42H、41H、40H的内容全部清“0”。本章小结 中断系统可以及时的响应和处理突发的事件
23、;通过定时计/数器可以实现有关于频率及时间的控制。中断系统一共有五个中断源,分别是外部中断0、外部中断1、定时/计数器0中断、定时/计数器1中断、以及串行口中断。外部中断有两种触发方式分别是低电平触发和下降沿触发。对中断进行控制有三个特殊功能寄存器TCON、IE、IP。其中TCON用来设置外部中断的触发方式,还包含四个中断请求标志位。IE用来设置中断的开放与关断,IP用来设置中断的优先级。中断编程一般要先进行中断初始化,即先通过指令对中断控制位进行设置。本章小结 定时/计数器可用于定时控制、延时、对外部事件计数和检测等场合。MCS-51单片机内部有两个定时/计数器T0、T1。T0由TH0和TL0组成,T1由TH1和TH0组成。定时/计数器有定时模式和计数模式两种模式。其中定时模式下可用来定时,计数模式下可以对外部脉冲信号进行计数。四种工作方式:方式0、方式1、方式2、方式3。方式0是13位定时/计数器,方式1是16位定时/计数器,方式2是8位自动重置初值定时/计数器,方式3下T0可分为两个8位定时/计数器,T1停止计数。定时/计数器的启动停止由TCON中的TR0和TR1控制,定时/计数器的工作方式选择由TMOD中的M1,M0设置。一般方式1可用来进行较长时间定时,方式2可用来进行精确定时,方式3可用来作为串行口的波特率发生器。在编程时,首先要对定时/计数器的各个控制位进行设置。