MCS-51单片机内部共有两个16位可编程定时/计数器:定时/计数器0和定时/计数器1。在51单片机中,定时/计数器的定时功能和计数功能是由同一种硬件完成的。它们的区别在于计数器的计数脉冲来源于单片机的外部脉冲,而定时器的脉冲来源于单片机的内部(它的脉冲频率取决于单片机的晶振频率)。
4.3.3.1 定时/计数器的结构
MCS-51单片机有两个可编程16位内部定时/计数器,其结构如图4-14所示。定时/计数器由初值寄存器TH0、TL0、TH1、TL1、中断控制寄存器TCON和工作方式控制寄存器TMOD等6个特殊功能寄存器组成。这6个特殊功能寄存器通过内部数据总线与CPU相连接,CPU通过数据总线向TCON、TMOD发送控制命令和读取状态信息,向TH0、TL0、TH1、TL1传送定时计数用初值,当定时器/计数器T0和T1溢出时,将TCON中的定时/计数器中断标志置1,并向CPU发出中断请求。两个定时/计数器有4种工作方式(方式0、方式1、方式2、方式3)可供选择。
计数器的计数都是从计数器的初值开始。单片机复位时计数器的初值为0,也可用软件给计数器装入一个新的初值。定时计数器工作时,不占用CPU的时间。
4.3.3.2定时/计数器的工作原理
定时/计数器有两种用途:定时器和计数器。但一个定时/计数器(T1或T0)不能既做定时器又做计数器。其实,定时/计数器的核心是一个加1计数器,脉冲来源有两个:一个是由系统的时钟晶振器输出脉冲经12分频后送来;另一个是由T0或T1引脚(P3.4或P3.5)输入的外部脉冲源提供。这就是51单片机中定时/计数器的定时功能和计数功能的区别(前者是定时器,后者是计数器)。每来一个脉冲则加1计数器加1,当加到加1计数器为全1时,再来一个脉冲就使加1计数器回到零;且加1计数器的溢出使得TCON寄存器中的TF0(或TF1)置1,向CPU发出中断请求。如果定时/计数器工作于定时模式,则表示定时时间已到;如果定时/计数器工作于计数模式,则表示计数值已满。
图4-14 MCS-51单片机内部定时/计数器的结构
所以定时器的定时时间不仅与计数器的初值有关,而且还与系统的时钟频率有关,在实际使用中要根据时钟频率来确定定时器的初值。
定时/计数器用作计数器时,计数器对来自T0(P3.4)和T1(P3.5)的外部脉冲计数,在每个机器周期的S5P2期间采样引脚输入电平。如果前一个机器周期采样值为1而后一个机器周期采样值为0,则说明有一个脉冲,计数器值加1。新的计数初值于下一个机器周期的S3P1期间装入计数器中。由于此种方式需要两个机器周期来检测一个从“1”到“0”的负跳变信号。因此,最高的计数频率为时钟频率的1/24。
当设置了工作方式并启动定时/计数器开始工作后,定时/计数器就按照设定的工作方式工作,不需要CPU的干预。当定时/计数器值为全1时,如果再输入一个脉冲则计数器重新回到全0,同时把定时/计数器的溢出标志位(TF1或TF0)置位,作为定时/计数器的溢出标志。
定时/计数器有两个控制寄存器,即TMOD和TCON。TMOD用于控制定时/计数器的工作方式,选择定时或计数功能;TCON则用于控制定时/计数器的启动和停止,并控制定时/计数器的工作状态等。启动定时/计数器开始工作之前,需要定义定时/计数器的工作方式,同时对TL0、TH0及TL1、TH1进行初始化编程。下面介绍TCON、TMOD寄存器的结构。
(1)定时/计数器的控制寄存器TCON。
TCON字节地址为88H,用于控制定时/计数器的启、停,标志定时器溢出和中断情况。可以按位寻址,其结构如表4-16所列。
表4-16 TCON寄存器结构
其各个位的含义和功能如下:
IT0:外部中断0触发方式选择位。IT0=0时,低电平触发方式,INT0引脚上低电平有效;IT0=1时,下降沿触发方式,INT0引脚上的电平由高到低的负跳变有效。
IE0:外部中断0请求标志位。当IT0=0时,为低电平触发方式,每个机器周期为S5P2采样INT0引脚。若INT0引脚为低电平,则IE0置1,否则IE0清0;当IT0=1时,为下降沿触发方式,当第一个机器周期采样到INT0为低电平时,则IE0置1。IE0=1表示外部中断0正在向CPU请求中断。但CPU响应中断该位由硬件清0。
IT1:外部中断1触发方式选择位。功能同IT0,但是IT1的工作对象是INT1。
IE1:外部中断1请求标志位。功能同IE0,但是IE1的工作对象是INT1。
TR0:T0运行控制位。TR0=1,启动定时器;TR1=0,关闭定时器,由软件控制。
TF0:T0溢出标志位。当T0计数满溢出时,硬件将TF0置1,并申请中断。进入服务程序后,由硬件将TF0自动清0。需要注意的是,如果使用定时器的中断,那么该位不需人工操作,但是如果使用软件查询方式,当查询到该位置1后,须用软件清0。
TR1:T1运行控制位。功能同TR0,但是TR1的工作对象是T1。
TF1:T1溢出标志位。功能同TF0,但是TF1的工作对象是T1。
(2)定时器工作方式寄存器TMOD。
TMOD字节地址为89H,用来确定定时器的工作方式及功能选择,不能按位寻址,结构如表4-17所列。各个位的含义及功能如下所述。注意:除方式3外,在其他3种工作下T0和T1功能完全相同。
M1、M0:工作方式选择位。M1M0=00,方式0,13位定时/计数器,最大计数8192次;M1M0=01,方式1,16位定时/计数器,最大计数65536次;M1M0=10,方式2,8位自动重装定时/计数器,最大计数256次;M1M0=11,方式3,把T0分为两个8位定时/计数器,最大计数256次。
C/:定时器工作方式控制位。C/=0,定时工作方式,脉冲来自单片机的内部;C/=1:计数工作方式,脉冲由外部提供。
GATE:门控位。当GATE=0时,计数器不受外部控制;当GATE=1时,计数器T0和T1分别受P3.2和P3.3引脚上的电平控制。当P3.2(或P3.3)引脚为高电平时,置TR0(或TR1)为1,计数器T0(或T1)开始计数;当P3.2(或P3.3)引脚为低电平时,计数器T0(或T1)停止计数。
表4-17 TMOD寄存器结构
当定时/计数器为计数模式时,计数脉冲是T0或T1引脚上的外部脉冲。这时,门控位GATE具有特殊的作用。GATE的逻辑结构图如图4-15所示。
当GATE=0时,经反相后使“或门”输出为“1”,此时仅由TR.x控制“与门”的开启,“与门”输出“1”时,控制开关接通,计数开始;当GATE=1时,由外中断引脚信号控制“或门”的输出,此时控制“与门”的开启由外中断引脚信号INT.x和TR.x共同控制。当TR.x=1时,外中断引脚信号INT.x的高电平启动计数,低电平停止计数。这种方式常用来测量外中断引脚上正脉冲的宽度。
图4-15 GATE门控制位结构
注:TR.x为TR0和TR1的简写,INT.x为INT0和INT1的简写。
4.3.3.3 定时/计数器的工作方式
(1)方式0。
方式0为13位计数,由TL0的低5位(高3位未用)和TH0的8位组成。TL0的低5位溢出时向TH0进位;TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求。方式0定时/计时器逻辑结构图如图4-16所示。
当定时/计数器工作方式为方式0时,假设单片机的机器周期为Tcy,定时产生一次中断的时间为t,那么需要计数的个数N=t/Tcy,装入TH.x和TL.x中的初值分别为:
TH.x=(8192-N)/32 TL.x=(8192-N)%32(www.xing528.com)
由于定时/计数器方式为13位计数器,即最多能装载最大数值为213=8192个。当TL.x和TH.x的初值为0时,最多经过8192个机器周期该计数器就会溢出一次,并向CPU申请中断。
图4-16 方式0定时/计数器逻辑结构图
(2)方式1。
方式1的计数位数是16位,由TL0作为低8位、TH0作为高8位组成了16位加1计数器。方式1定时/计数器逻辑结构图如图4-17所示。
当定时/计数器工作方式为方式1时,假设单片机的机器周期为Tcy,定时产生一次中断的时间为t,那么需要计数的个数N=t/Tcy,装入TH.x和TL.x中的初值分别为:
TH.x=(65536-N)/256 TL.x=(65536-N)%256
图4-17 方式1定时/计数器逻辑结构图
由于定时/计数器方式为16位计数器,即最多能装载最大数值为216=65536个。当TL.x和TH.x的初值为0时,最多经过65536个机器周期该计数器就会溢出一次,并向CPU申请中断。
(3)方式2。
在定时/计数器的方式0和方式1中,当计数器溢出后,计数器变为0。因此在循环定时或循环计数时必须要用软件反复设置计数初值,这必然影响到定时的精度,同时也给程序设计带来很多麻烦。定时/计数器方式2则可解决软件反复重装初值所带来的问题,在计数器溢出后,计数器自动将上次设置的初值重装。所以方式2适合做较精确的脉冲信号发生器,但由于它只有8位计数器,当定时较长时间时也会给编程带来麻烦,同时也可能影响到精度。所以当我们对定时精度要求不高时,使用方式0或方式1比较合适。若要做精确的频率较高的信号发生器时才选用方式2。但也要注意,此时的晶振频率务必要选择12的整数倍,因为定时器的频率是晶振频率的1/12。
方式2为自动重装初值的8位计数方式。方式2定时/计数器逻辑结构图如图4-18所示。
图4-18 方式2定时/计数器逻辑结构图
当定时/计数器工作方式为方式2时,假设单片机的机器周期为Tcy,定时产生一次中断的时间为t,那么需要计数的个数N=t/Tcy,装入TH.x和TL.x中的初值分别为:
TH.x=256-N TL.x=256-N
由于定时器方式2为8位计数器,即最多能装载的数为28=256个。当TL.x和TH.x的初值为0时,最多经过256个机器周期该计数器就会溢出。若使用12MHz的晶振,也只有256μs的时间。若使用11.0592MHz晶振,那么计算机器周期时,晶振自身产生的误差也已经不少了,再加上过程累加,误差便会更大。
(4)方式3。
方式3只适用于定时/计数器T0,定时器T1处于方式3时相当于TR1=0,T1不计数。方式3将T0分成两个独立的8位定时/计数器TL0和TH0,方式3定时/计数器逻辑结构图如图4-19所示。
图4-19 方式3定时/计数器逻辑结构图
TL0为正常的8位定时/计数器,计数溢出后置位TF0,并向CPU申请中断,之后再重装初值。TH0也被固定为一个8位定时/计数器,不过由于TL0已经占用了TF0和TR0,因此这里的TH0将占用定时/计数器T1的中断请求标志位TF1和定时/计数器T1的启动控制位TR1。
这里需要强调一点,因为定时/计数器T0在方式3时会占用定时/计数器T1的中断标志位,为了避免中断冲突,设计程序时一定要注意。当T0工作在方式3时,T1一定不要用在有中断的场合,T1照样可以正常工作在方式0、方式1、方式2下,但无论哪种工作方式都不可以使用它的中断,因为T0要使用T1的中断。通常在这种情况下,T1用作串行口的波特率发生器。
4.3.3.4 定时/计数器的初始化
初始化程序应完成如下工作:
①对TMOD赋值,以确定T0和T1的工作方式。
②计算初值,并将其写入TH0、TL0或TH、TL1。
③使用中断方式时,则对IE赋值,开放中断。
④使TR0或TR1置位,启动定时/计数器的定时或计数。
(1)初值的计算。
假设定时器工作在工作方式1,位数是16位。定时器一旦启动,便在原来的数值上开始加1计数。若在程序开始时我们没有设置TH.x和TL.x,则它们的默认值为0。假设时钟频率为12 MHz,12个时钟周期为一个机器周期,那么此时机器周期就是1μs,计满TH.x和TL.x就需要计数最大值-1。再来一个脉冲后计数器就会溢出,随即向CPU申请中断。因此溢出共需要65536μs,约等于65.5 ms。
若要定时50 ms,那么就要先给TH.x和TL.x装初值。TH.x和TL.x中应该装人的总数为65536-50000=15536,把15536对256求商15536/256=60装入TH.x中;把15536对256求余15536%256=176装入TL.x中。在这个初值的基础上计50000个数后定时溢出,此时刚好就是50 ms中断一次。若要定时1s,由于定时/计数器的最大定时时长为65536μs,不能像定时50 ms那样直接给定时/计数器赋1000000μs的初值,可以累计定时/计数器产生50 ms中断的次数。当中断的次数达到20时就定时到了20×50 ms=1 s。20次50 ms中断时为1s,这样才可以准确控制定时时长。
(2)Keil C中断服务程序的写法。
C51的中断函数格式如下:
中断函数中不能返回任何值,所以在最前面用void;“函数名”可以更改,由用户自定义,但不能和C51的关键字相同;“中断函数”也不能带任何参数,所以“函数名”后面是个空的小括号;“中断号”是指单片机中几个中断源的序号。这个序号是编译器识别不同中断的唯一符号,因此,在编写中断服务程序时务必书写正确;最后的“using工作组”是指这个中断函数使用单片机内存中4组工作寄存器中的哪一组。C51编译器在编译程序时会自动分配工作组,因此“using工作组”可以省略不写。
4.3.3.5 定时器应用
例4-3 根据例4-1原理图,在P1.0口产生周期为20 ms的方波信号。
代码如下:
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。