首页 理论教育 汇编与C语言实战:MCS-51单片机定时/计数器解析

汇编与C语言实战:MCS-51单片机定时/计数器解析

时间:2023-10-23 理论教育 版权反馈
【摘要】:定时/计数器是MCS-51系列单片机的重要部件,其工作方式灵活,编程简单,它的使用大大减轻了CPU的负担并且简化了外围电路。图6-2是MCS-51系列单片机内部定时/计数器结构框图。

汇编与C语言实战:MCS-51单片机定时/计数器解析

定时/计数器是MCS-51系列单片机的重要部件,其工作方式灵活,编程简单,它的使用大大减轻了CPU的负担并且简化了外围电路。

在MCS-51系列单片机中,51子系列单片机有2个定时/计数器T0和T1,52子系列单片机除了有上述两个定时/计数器以外,还有一个定时/计数器T2,后者的功能比前两者强。图6-2是MCS-51系列单片机内部定时/计数器结构框图。

图6-2 MCS-51系列单片机内部定时/计数器结构框图

从图6-2可见,定时/计数器主要由几个特殊功能寄存器TH0、TL0、TH1、TL1以及TMOD、TCON组成。定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。其中:TH0(高8位)、TL0(低8位)构成16位加1计数器T0,用来存放T0的计数初值;TH1(高8位)、TL1(低8位)构成加116位计数器T1,用来存放T1的计数初值,这两个16位计数器都是16位的加1计数器。TMOD用来控制两个定时/计数器的工作方式,TCON用作中断溢出标志并控制定时器的启停。

加1计数器输入的计数脉冲有两个来源。其中:一个是由系统的时钟振荡器输出脉冲经12分频后送来;另一个是T0或T1引脚输入的外部脉冲源。每来一个脉冲计数器加1,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使TCON中TF0或TF1置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。因此,由溢出时计数器的值减去计数初值才是加1计数器的计数值。

(1)设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期T cy就是定时时间t。

(2)设置为计数器模式时,外部事件计数脉冲由T0或T1引脚输入到计数器。在每个机器周期的S5P2期间采样T0、T1引脚电平。当某周期采样到一高电平输入,而下一周期又采样到一低电平时,则计数器加1,更新的计数值在下一个机器周期的S3P1期间装入计数器。由于检测一个从1到0的下降沿需要2个机器周期,因此要求被采样的电平至少要维持一个机器周期。当晶振频率为12MHz时,最高计数频率不超过1/2MHz,即计数脉冲的周期要大于2μs。

两个定时/计数器都可由软件设置为定时或计数的工作方式,其中T1还可作为串行口的波特率发生器。不论T0或T1是工作于定时方式还是计数方式,它们在对内部时钟或外部事件进行计数时,都不占用CPU时间,直到定时/计数器产生溢出。如果满足条件,CPU才会停下当前的操作,去处理“时间到”或者“计数溢出”这样的事件。因此,定时/计数器是与CPU“并行”工作的,不会影响CPU的其他工作。

6.2.2.1 定时器/计数器的控制寄存器

单片机定时/计数器T0、T1的工作主要由TMOD、TCON、IE 3个特殊功能寄存器控制。其中:TMOD用来设置各个定时/计数器的工作方式、选择定时或计数功能。TCON用于控制启动运行以及作为运行状态的标志等。IE用于对定时/计数器中断允许进行控制。

1.工作方式控制寄存器TMOD

TMOD寄存器是一个用于设定定时/计数器工作方式的特殊功能寄存器,其低4位用于控制T0,而高4位用于控制T1。字节地址为89H,不能位寻址,设置TMOD须用字节操作指令。复位时TMOD为00H。它的各位定义见图6-3。

图6-3 TMOD各位定义

(1)M1、M0:工作方式选择位。M1、M0用来选择工作方式,对应关系如表6-1所示。

表6-1 定时/计数器的方式选择

(2)img:定时/计数功能选择位。img为定时方式。在定时方式中,以振荡输出时钟脉冲f osc的12分频信号作为计数信号,如果单片机采用12MHz晶体,则计数频率为1MHz,计数脉冲周期为1μs,即每1μs计数器加1一次。

C/img=1为计数方式,在计数方式中,单片机在每个机器周期对外部计数脉冲进行采样。如果前一个机器周期采样为高电平,后一个机器周期采样为低电平,即为一个有效的计数脉冲。在下一机器周期进行计数。因此,外部事件计数时最高计数频率是单片机晶振频率的1/24。如果单片机采用12MHz晶体,则外部事件计数脉冲最短周期为2μs,即最快可以做到每2μs计数器加1。

(3)GATE:门控位_。GATE=1,定时/计数器的运行受外部引脚输入电平的控制,即img控制T0运行,img控制T1运行;GATE=0,定时/计数器的运行不受外部输入引脚的控制。

2.定时器控制寄存器TCON

TCON寄存器是一个用于控制启动运行以及作为运行状态的标志的特殊功能寄存器。TCON寄存器既参_与定_时控制又参与中断控制,其高4位用于控制T0、T1,而低4位用于控制外部中断img。TCON的字节地址为88 H,它可位寻址。复位时TCON为00H。它的各位定义见图6-4。

图6-4 TCON各位定义

TCON低4位与外中断img有关,已在本书的前面中断系统部分叙述过,下面对与定时控制有关高4位功能加以说明。

(1)TF0和TF1:计数溢出标志位。当计数器计数溢出(计满)时,该位置1。使用查询方式时,此位作状态位供查询,但应注意查询有效后应用软件方法及时将该位清0;使用中断方式时,此位作中断标志位,在转向中断服务程序时由硬件自动清0。

(2)TR0和R1:定时器运行控制位。TR0(TR1)=0,停止定时/计数器工作;TR0(TR1)=1,启动定时/计数器工作。该位根据需要靠软件来置1或清0,以控制定时器的启动或停止。

3.中断允许控制寄存器IE

IE寄存器与定时/计数器有关的位为ET0和ET1,它们分别是定时/计数器0、1的中断允许控制位。当ET0(或ET1)=0时,禁止定时/计数器0(或1)中断;而当ET0(或ET1)=1时,允许定时/计数器0(或1)中断。

6.2.2.2 定时器/计数器的工作方式

1.方式0

方式0是13位计数结构的工作方式,定时/计数器T0、T1都可以设置工作方式0,T0(或T1)的计数器由TH0(或TH1)高8位和TL0(或TL1)的低5位构成,TL0(或TL1)的高3位未用。下面以定时/计数器0为例来介绍一下这种方式,图6-5、图6-6分别为工作方式0的逻辑电路结构、工作原理框图。当TL0的低5位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求。

img时,多路开关接通振荡脉冲的12分频输出,13位计数器以此进行计数,这就是定时方式。

img时,多路开关接通计数引脚P3.4(T0),外部计数脉冲由引脚P3.4输入。当计数脉冲发生负跳变时,计数器加1,这就是计数方式。

不管是定时方式还是计数方式,当TL0的低5位计数溢出时,向TH0进位,而全部13位计数溢出时,则向计数溢出标志位TF0进位。在满足中断条件时,向CPU申请中断,若需继续进行定时或计数,则应用指令对TL0、TH0重新置数,否则,下一次计数将会从0开始,造成计数或定时时间不准确。

图6-5 工作方式0的逻辑电路结构

图6-6 工作方式0的工作原理框图

这里要特别说明的是:T0能否启动,取决于TR0、GATE和引脚img的状态。

当GATE=0时,GATE信号封锁了或门,使引脚img信号无效。而或门输出端的高电平状态却打开了与门。这时如果TR0=1,则与门输出为1,模拟开关接通,定时/计数器0工作。如果TR0=0,则断开模拟开关,定时/计数器0不能工作。

当GATE=1,同时TR0=1时,模拟开关是否接通由img控制。当img时,与门输出高电平,模拟开关接通,定时/计数器0工作;当img时,与门输出低电平,模拟开关断开,定时/计数器0停止工作。这种情况可用于测量外信号img脉冲宽度

方式0是13位的定时/计数方式,因而最大计数值(满值)为M=213=8192。若计数值为N,则置入的初值X为

X=8192-N

例如,定时/计数器T0的计数值为1000,则初值为7192,转换成二进制数为1110000011000B,则TH0=11100000B=E0H,TL0=xxx11000B=18H(把xxx当作000时)。

2.方式1

方式1是16位计数结构的工作方式,定时/计数器T0、T1都可以设置工作方式1,T0(或T1)的计数器由TH0(或TH1)高8位和TL0(或TL1)的低8位构成,其逻辑电路和工作情况与工作方式0基本相同。下面以定时/计数器0为例来介绍一下这种方式,图6-7、图6-8分别为工作方式0的逻辑电路结构、工作原理框图。所不同的只是组成计数器的位数,它比工作方式0有更宽的计数范围,因此,在实际应用中,工作方式1可以代替工作方式0。

图6-7 工作方式1的逻辑电路结构

图6-8 工作方式1的工作原理框图

由于是16位的定时/计数方式,因而最大计数值(满值)为M=216=65536。若计数值为N,则置入的初值X为

X=65536-N

例如,定时/计数器T0的计数值为1000,则初值为65536-1000=64536,转换成二进制数为1111110000011000B,则TH0=11111100B=FCH,TL0=00011000B=18 H。

3.方式2

方式0、方式1若用于循环重复定时或计数时,每次计满溢出后,计数器回到0,要进行新一轮的计数,就得重新装入计数初值。因此,循环定时或循环计数应用时就存在反复设置计数初值的问题,这项工作是由软件完成的,需要花费一定时间,造成每次计数或定时产生误差,这对用于一般的定时,可能无关紧要,但是有些工作,对时间的要求非常严格,不允许定时时间不断变化,用方式0、方式1就不行了,所以就引入了方式2,因为工作方式2的计数初值是自动装入的。

方式2为具有自动重装初值的、8位计数结构的工作方式,定时/计数器T0、T1都可以设置工作方式2。在方式2下,16位计数器被分为两部分,即以TL0(或TL1)作计数器,而以TH0(或TH1)作预置寄存器(即保存计数初值),初始化时把8位的计数初值分别装入TL0(或TL1)和TH0(或TH1)中。当TL0(或TL1)计数溢出后,不是像前两种工作方式那样通过软件方法,而是由预置寄存器TH0(或TH1)以硬件方法自动给计数器TL0(或TL1)重新加载。也就是溢出信号一方面使TF0(或TF1)置位,另一方面溢出信号又会触发上图中的三态门,使三态门导通,TH0(或TH1)的值就自动装入TL0(或TL1)。从而变方式0、方式1的软件加载为硬件加载。这样不但省去了用户程序中的重装指令,而且也有利于提高定时精度。因此,方式2特别适合于用作较精确的脉冲信号发生器。下面以定时/计数器0为例来介绍一下这种方式,图6-9、图6-10分别为工作方式2的逻辑电路结构、工作原理框图。

图6-9 工作方式2的逻辑电路结构

图6-10 工作方式2的工作原理框图

由于是8位的定时/计数方式,因而最大计数值(满值)为M=28=256。若计数值为N,则置入的初值X为

X=256-N

例如,定时/计数器T0的计数值为100,则初值为256-100=156,转换成二进制数为10011100B,则TH0=TL0=10011100B。

注意:由于方式2计满后,溢出信号会触发三态门自动地把TH0(或TH1)的值装入TL0(或TL1)中,因而如果要重新实现N个单位的计数,不用重新置入初值。

4.工作方式3

工作方式3的作用比较特殊,只适用于定时器T0。如果企图将定时器T1置为方式3,则它将停止计数,其效果与置TR1=0相同,即关闭定时器T1。

当T0工作在方式3时,它被拆成两个独立的8位计数器TL0和TH。图6-11、图6-12分别为工作方式3的逻辑电路结构、工作原理框图。

图6-12中,下方的8位计数器TL0使用原定时器T0的控制位img、GATE、TR0和img,TL0既可以计数使用,又可以定时使用,其功能和操作与前面介绍的工作方式0或工作方式1完全相同。上方的TH0只能作为简单的定时器使用。而且由于定时/计数器0的控制位已被TL0独占,因此只好借用定时/计数器1的控制位TR1和TF1。即以计数溢出

图6-11 工作方式3的逻辑电路结构

图612 工作方式3的工作原理框图(www.xing528.com)

去置位TF1,而定时的启动和停止则受TR1的状态控制。

由于TL0既能作定时器使用也能作计数器使用,而TH0只能作定时器使用却不能作计数器使用,因此在工作方式3下,定时/计数器0可以构成两个定时器或一个定时器和一个计数器。注意:在方式3下,T0和T1的工作有很大的不同。其差别如下:

(1)若把T1置于方式3,则T1停止计数,其效果与置TR1=0相同,即关闭定时器T1。此时,定时器T1保持其内容不变。因此,一般不会把T1置于方式3。

(2)若把T0置于方式3,则16位计数器拆开为两个独立工作的8位计数器TL0和TH0。但这两个8位计数器的工作是有差别的。首先,它们的工作方式不同:①对TL0来说它既可以按计数方式工作,也可以按定时方式工作;②而TH0则只能按定时方式工作。另外,它们的控制方式也不同。

(3)当T0处于方式3时,此时T1可工作为方式0、1、2,但由于此时T1已没有控制通断TR1和溢出中断TF1的功能,T1只能作为串行口的波特率发生器使用,或不需要中断的场合。

6.2.2.3 定时器/计数器的计数初值计算

MCS-51的定时器/计数器采用增量计数。根据定时/计数器的计数结构,其最大计数为2m,其中m为计数器的位数,对于工作方式0,m=13,其最大计数为213=8192;对于工作方式1,m=16,其最大计数为216=65536;对于工作方式2和工作方式3,m=8,其最大计数为28=256。

在实际应用中,经常会有少于2m个计数值的要求,例如,要求计数到1000就产生溢出,这时可在计数时,不从0开始,而是从一个固定值开始,这个固定值的大小,取决于被计数的大小。如要计数1000,预先在计数器里放进(2m-1000)的数,再来1000个脉冲,就到了2m,就会产生溢出,置位TF0。这个(2m-1000)的数称作计数初值,也称作预置值。

定时也有同样的问题,并且也可采用同样的方法来解决。当定时/计数器为工作方式0,并假设单片机的晶振是12MHz,那么每个计时脉冲是1μs,计满213=8192个脉冲需要8.192ms,如果只需定时1ms,可以作这样的处理:1ms即1000μs,也就是计数1000时满。因此,计数之前预先在计数器里放进213-1000=8192-1000=7192,开始计数后,计满1000个脉冲到8192即产生溢出。如果计数初值为X,则计算定时时间t为

t=(2N-X)×T cy=(2N-X)×12/f osc

式中:T cy为机器周期,f osc为晶振周期。

例如,如果定时/计数器为工作方式0,需要定时3ms(3000μs),f osc为12MHz。设计数初值为X,则根据上述公式可得:

3000=(2m-X)×12/f osc=(213-X)×12/12

由此可得,X=5192。

需要说明的是,单片机中的定时器通常要求不断重复定时,一次定时时间到之后,紧接着进行第二次的定时操作。一旦产生溢出,计数器中的值就回到0,下一次计数从0开始,定时时间将不正确,为使下一次的定时时间不变,需要在定时溢出后马上把计数初值送到计数器。

6.2.2.4 定时/计数器的初始化编程及应用

定时器/计数器的功能是由软件编程确定的,在使用定时器,计数器前都要对其进行初始化。MCS-51单片机定时/计数器的初始化编程步骤为:

(1)根据要求选择方式,确定方式控制字,写入方式控制寄存器TMOD。例如,MOV TMOD,#10 H,表明定时器1工作在方式1,且工作在定时器方式。而定时器0工作在方式0,且工作在定时器方式。

(2)根据定时时间要求或计数要求,计算定时/计数器的计数值,再由计数值求得初值,送计数初值的高8位和低8位到TH0(或TH1)和TL0(或TL1)寄存器中。

定时/计数器的初值因工作方式的不同而不同。设最大计数值为M,则各种工作方式下的M值为:方式0时M=213=8192;方式1时M=216=65536;方式2时M=28=256;方式3时,T0分成两个8位计数器,所以两个定时器的M值均为M=256。由于定时器计数器工作的实质是做“加1”计数,所以,当最大计数值M值为已知且计数值为N时,初值X可计算为

X=M-N

(3)如果工作于中断方式,则根据需要开放定时/计数器的中断,即对IE寄存器赋值(后面还需编写中断服务程序)。

(4)设置定时/计数器控制寄存器TCON的值(即将其TR0或TR1置位),启动定时/计数器开始工作。

(5)等待定时/计数时间到,定时/计数到则执行中断服务程序。若用查询处理,则需编写查询程序判断溢出标志,溢出标志等于1,则进行相应处理。

【例6-2】 T0运行于定时器状态,时钟振荡周期为12MHz,要求定时100μs。试求不同工作方式时的定时初值X。

当f osc=12MHz,时,T cy=1μs,N=100μs/1μs=100=64 H

方式0(13位方式):X=213-64H=1F9CH

方式1(16位方式):X=216-64 H=FF9CH

方式2、3(8位方式):X=28-64H=9CH

注意:工作方式0的初值装入方法:

可见,TH0=0FCH,TL0=1CH(若×××当作000)

MOV TH0,#0FCH

MOV TL0,#1CH

6.2.2.5 定时器/计数器的应用举例

【例6-3】 设系统时钟频率为12MHz,利用定时器/计数器T0编程实现从P1.0输出周期为20ms的方波

从P1.0输出周期为20ms的方波,只需P1.0每隔10ms取反一次。当系统时钟为12MHz,定时器/计数器T0工作于方式1时,最大的定时时间为65536us,满足10ms的定时要求。系统时钟为12MHz,计数值为10000,初值X=65536-10000=D8F0H,则TH0=D8 H、TL0=F0 H。

1.采用查询方式编程

汇编语言参考程序为:

C语言参考程序为:

2.采用中断方式编程

汇编语言参考程序为:

C语言参考程序为:

图6-13 例6-4的电路图

如果定时时间大于65536μs,这时用一个定时/计数器直接处理不能实现,这时可用:①1个定时/计数器配合软件计数方式处理;②2个定时/计数器共同处理。

【例6-4】 如图6-13所示,在P1.7端接一个发光二极管LED,要求利用定时控制使LED亮1s灭1s周而复始地闪烁,设时钟频率fosc=6MHz。

当f osc=6MHz时,工作方式0、1、2均不能满足定时1s的要求。如16位定时最大为216×2μs=131.072ms,显然不能满足要求,可用以下两种方法解决。

方法1:采用T0产生周期为200ms脉冲,即P1.0每100ms取反一次作为T1的计数脉冲,T1对下降沿计数,因此T1计5个脉冲正好1s。通过P1.7反相,改变LED的状态。

T0采用方式1,定时100ms。计数初值为:X=216-100×103/2=3CB0H。

T1采用方式2,计5个脉冲,计数初值:X=28-5=FBH。

均采用查询方式,其流程图如图6-14所示。

汇编参考程序为:

图6-14 例6-4的流程图

C语言参考程序为:

方法2:T0每隔100ms中断一次,利用软件对T0的中断次数进行计数,中断10次即实现了1s的定时。

采用C语言完成本例的方式1。T0定时100ms初值=100×1000/2=50000,即初值为-50000。T1计数5个脉冲工作于方式2,计数初值为-5,T0和T1均采用中断方式。

C语言参考程序为:

【例6-5】 利用定时器T0测量某正脉冲信号宽度,脉冲从P3.2(即img)输入。已知此脉冲宽度小于10ms,系统时钟频率为12MHz。要求测量此脉冲宽度,并把结果顺序存放在以片内30 H单元为首地址的数据存储单元中。

利用门控位的功能,当GATE为1时,只有img且软件使TR0置1,才能启动定时器。利用这个特性,便可测量输入脉冲的宽度(系统时钟周期数)。

汇编参考程序为:

C语言参考程序为:

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈