3.1定时器/计数器3.1.1单片机定时器/计数器的结构1.定时器/计数器的组成结构MCS-51单片机内部有两个定时器/计数器(T0和T1)。它们都是16位的加法计数器,可用于定时控制和对外部事件的计数。当用于定时操作时,实际上就是通过计数器对单片机内部时钟电路产生的固定周期脉冲信号进行加法计数;当用于计数操作时,实际上就是对外部事件产生的脉冲信号进行加法计数。可见,不管是定时操作还是计数操作,都要由16位加法计数器完成。如果计数器事先设置的初始状态不同,那么从开始计数到计满溢出为止所用的时间也就不同。因此,使用T0或T1时要为其设置初始值,可通过软件完成。定时器/计数器T0由两个8位的特殊功能寄存器(TH0和TL0)组成,T1由TH1和TL1组成。定时、计数功能是通过两个特殊功能寄存器(TMOD和TCON)控制的。如果定时器/计数器T0和T1相当于两台电视机,那么特殊功能寄存器TMOD、TCON就相当于电视机上的控制按钮。因此,掌握TMOD、TCON的功能是用好T0、T1的关键。图3.1MCS-51定时器/计数器逻辑结构图2.定时器/计数器的方式寄存器和控制寄存器1)定时器/计数器的方式寄存器定时器/计数器的方式寄存器(TMOD)用于控制T0和T1的操作方式,其字节地址为89H,是一个8位的特殊功能寄存器。使用时分为高4位和低4位两部分,其中高4位控制T1,低4位控制T0。各位的含义如图3.2所示。图3.2TMOD的各位含义(1)GATE:门控位。用于控制T0或T1的启动。当GATE=0时,计数器的启动不受外部引脚信号INT0或INT1控制,只受特殊功能寄存器TCON中的启动位TR0或TR1控制;当GATE=1时,计数器的启动不仅受TR0或TR1控制,还要受外部引脚信号INT0或INT1控制。(2)C/T:定时器或计数器功能选择位。当C/T=1时,作为计数器实现对外部脉冲计数;当C/T=0时,作为定时器实现定时控制。(3)M1和M0:工作方式选择位。定时器/计数器有4种工作方式,可通过M1、M0的二进制组合取值选择不同的工作方式。对应关系见表3-1。表3-1定时器工作方式的选择M1M0工作方式说明00方式0T0或T1是13位定时器/计数器01方式1T0或T1是16位定时器/计数器10方式2是常数自动重装的8位定时器/计数器11方式3被拆为两个8位定时器/计数器,仅适用于T02)定时器/计数器的控制寄存器定时器/计数器的控制寄存器(TCON)用于控制定时器/计数器T0或T1的运行,是一个8位的特殊功能寄存器,其字节地址为88H。低4位与中断有关,这里只介绍高4位。高4位中的高两位控制T1,低两位控制T0。(1)TF1:定时器/计数器T1的溢出标志位。当T1计满溢出时,系统自动将此位置1,并向CPU发出中断申请。当CPU响应中断时,由硬件自动将该位清0。(2)TR1:定时器/计数器T1的运行控制位。用于控制T1的启动和停止。当TMOD的门控位GATE=0时,仅通过TR1置1就可以启动T1计数;当门控位GATE=1时,需要TR1置1并且INT1为高电平,只有这两个信号同时存在才能启动T1计数。(3)TF0:定时器/计数器T0的溢出标志位。其功能与T1相同。(4)TR0:定时器/计数器T0的运行控制位。其功能与T1相同。3.1.2定时器/计数器的工作方式通过对TMOD的学习可知,M1、M0的不同取值可以决定定时器/计数器的工作方式。T0具有方式0、方式1、方式2和方式3四种工作方式;T1具有方式0、方式1和方式2三种工作方式。下面对各种工作方式进行说明。1.方式0当M1M0=00时,定时器/计数器工作在方式0下。方式0下的定时器/计数器是13位定时器/计数器。以T0为例,TH0和TL0本身都是8位寄存器,但当工作在方式0下时,TL0只用低5位,高3位未用。其逻辑结构如图3.4所示。在图中,TL0的低5位计满溢出时,将向TH0进位,当TH0计满溢出时,则将向TCON的TF0位进位,将该中断溢出标志位置1。从图3.4可以看出,T0是作为定时器还是作为计数器由C/T决定。当C/T=0时,多路开关与分频器相连,T0对振荡器12分频后的信号进行加法计数,即对机器周期进行计数。计一个脉冲需要一个机器周期,则其定时时间为:定时时间=(213-T0初值)×机器周期当C/T=1时,多路开关与T0引脚相连,对来自T0引脚的外部脉冲信号进行加法计数。门控位GATE=0时,或门输出A点恒为1,INT0无效,此时与门输出B点只受TR0控制。即TR0=1时,控制开关闭合,启动计数器;TR0=0时,控制开关断开,计数器停止计数。门控位GATE=1时,或门输出A点是1还是0取决于INT0的值。当INT0=1且TR0=1时,与门输出B点才为1,控制开关闭合,启动计数器计数。由此可见,当GATE=1时,启动计数器TR0和INT0必须都为1,两个条件缺一不可。2.方式1当M1M0=01时,定时器/计数器工作在方式1下。方式1下的T0是16位定时器/计数器。惟一与方式0不同的是,TH0和TL0的所有位都参与计数。定时时间=(216-T0初值)×机器周期3.方式2当M1M0=10时,定时器/计数器工作在方式2下。方式2下的定时器/计数器是常数自动重装的8位定时器/计数器。以T1为例,在方式2下,TL1作为8位定时器/计数器,TH1作为常数缓冲器。当TL1计满溢出时,将中断溢出标志位TF1置,同时将TH1中备用的计数常数自动送至TL1中,使TL1从初值开始重新计数。这种工作方式不用重装初值,省去了软件重装常数的程序,可以相当精确地定时。4.方式3当M1M0=11时,定时器/计数器T0工作在方式3下。这种工作方式不适用于T1,因为它是为附加一个8位定时器/计数器而设计的。此时,T1被拆为两个独立的8位计数器TL0和TH0。TL0使用T0的状态控制位,而TH0只能作为8位定时器(不能作为计数器),且使用T1的状态控制位。3.1.3定时器/计数器的编程和应用1.定时器/计数器的编程方法和步骤掌握TMOD、TCON及定时器/计数器的各种工作方式后,通常可按下列步骤实现定时和计数控制。(1)根据要求确定TMOD的初始值。通过设置TMOD的初始值,确定使用T0还是T1、选择方式0~方式3中的哪一种工作方式及启动方式等。(2)计算不同工作方式下定时或计数的初值。(3)编写初始化程序,通过软件控制定时器/计数器硬件电路的工作。在编写初始化程序的过程中,要通过指令把TMOD的初始值、定时或计数的初值装入相应寄存器中,并通过启动T0或T1来计数,同时采用查询方式或中断方式检查计数器是否溢出,并进行相应处理。2.定时器/计数器的应用举例【例3.1】设单片机的晶振频率为6MHz,试计算其最小和最大定时时间。定时时间与机器周期有关。当单片机晶振频率为6MHz时,一个机器周期为2μs。计算最小定时时间:定时器的4种工作方式的最小定时时间都是一样的,即定时器初值为最大值,8位定时器初值为FFH,13位为1FFFH,16位为FFFFH。Tmin=1×Tc=1×2μs=2μs计算最大定时时间:在方式1下定时时间最长。Tmax=216×2μs=131072μs≈0.13s应该注意,定时器的最大定时时间和最小定时时间随单片机的晶振频率变化而变化。【例3.2】设晶振频率为12MHz,用T0在方式0下产生1ms的定时,使P1.0脚上产生周期为2ms的方波(见图3.8)。根据题意,只要使P1.0每隔1ms取反一次即可得到2ms的方波。(1)按题目要求设置TMOD的初值。GATE=0(只通过TR0启动T0),C/T=0(定时操作),M1M0=00(方式0),所以(TMOD)=00H。(2)计算1ms方式0定时初始值。单片机的晶振频率为12MHz,则其机器周期为1μs。1ms×1000=(213-T0初值)×1μsT0初值=7192=1C18H=0001110000011000BTH0TL0取其低13位,高8位装入TH0,低5位装入TL0。因此(TH0)=0E0H,(TL0)=18H。(3)编写初始化控制程序。ORG2000HSTART:MOVTMOD,#00H;写入方式控制字MOVTL0,#18H;为T0装入初始值MOVTH0,#0E0HSETBTR0;启动T0LOOP:JBCTF0,PNG;定时时间到时转向PNGAJMPLOOP;若未到,则继续查询PNG:MOVTL0,#18H;为T0重装初始值MOVTH0,#0E0HCPLP1.0;取反AJMPLOOP;循环【例3.3】用T1在方式2下计数,要求每计满100次,就将P1.0脚取反。(1)根据要求设置TMOD的初值。GATE=0(只通过TR1启动T1),C/T=1(计数器功能),M1M0=10(方式2),所以TMOD=01100000B=60H。(2)计算计数初值。计数值=28-TL1初值,因此TL1初值=28-计数值=28-100=156=9CH,(TH1)=(TL1)=9CH。(3)编写初始化控制程序。ORG2000HSTART:MOVTMOD,#60H;写入方式控制字MOVTL1,#9CH;设置计数初始值MOVTH1,#9CHSETBTR1;启动T1LOOP:JBCTF1,DONE;若计满,则转向DONESJMPLOOP;否则等待DONE:CPLP1.0;取反输出SJMPLOOP【例3.4】设晶振频率为6MHz,T0工作在方式3下,TH0和TL0作为两个独立的8位定时器。要求用TL0定时200μs,在P1.0脚产生周期为400μs的方波;用TH0定时400μs,在P1.1脚产生周期为800μs的方波。本例采用中断方式。在方式3下工作,对于TH0来说,需要借用T1的控制信号。(1)根据要求设置TMOD的初值。(TMOD)=00000011B=03H(2)计算定时初始值。定时200μs的TL0在方式3下的初始值:200μs=(28-TL0初值)×2μs(TL0)=28-100=156=9CH定时400μs的TH0在方式3下的初始值:400μs=(28-TH0初值)×2μs(TH0)=256-200=56=38H第3章单片机的定时与中断系统·65··65·(3)编写初始化控制程序。ORG0000HBEGIN:AJMPMAINORG000BH;TL0的中断服务子程序AJMPINT0ORG001BH;TH0的中断服务子程序AJMPINT1ORG2000HMAIN:MOVTMOD,#03H;写入方式控制字MOVTL0,#9CH;设置计数初值MOVTH0,#38H;设置计数初值SETBEA;开中断SETBET0;允许T0中断SETBET1;允许T1中断SETBTR0;启动TL0SETBTR1;启动TH0LOOP:SJMPLOOPINT0:CPLP1.0MOVTL0,#9CH;重装初值RETI;中断返回INT1:CPLP1.1MOVTH0,#38HRETI【例3.5】用T0作为外部工件计数器,外部工件信号由T0端引入,T1作为定时器,每隔1s检测一次T0中的计数值,当检测到200个工件时,使P1.0输出信号变反,程序不断循环,控制P1.0的输出。设单片机的晶振频率为12MHz。(1)根据要求设置TMOD的初值。根据题意,可设置T0为计数方式,工作在方式2下;T1为定时方式,定时1s,工作在方式1下。(TMOD)=16H(2)计算定时、计数初始值。T0计数初值:TH0=28-200=56=38H,因此(TH0)=38H。T1定时初值:由于T1最大定时不足1s,因此可设定时50ms,工作在方式1下,再用软件计数循环20次。T1定时50ms的在方式1下的初值:50ms×1000μs=(216-T1初值)×1μsT1初值=216-50000=15536=3CB0H所以(TH0)=3CH,(TL0)=0B0H。(3)编写初始化控制程序。ORG2000HBEGIN:MOVTMOD,#16H;装入方式字MOVTH1,#3CH;设置T1的初值MOVTL1,#0B0HMOVTH0