第7章定时器/计数器本章主要内容7.1概述7.2MCS-51定时器/计数器结构7.3计数器方式寄存器和控制寄存器7.4定时器/计数器的工作方式7.5定时器/计数器的应用7.1概述MCS-51单片机内部共有两个16位可编程的定时器/计数器,定时器0和定时器1,它们既有定时功能又有计数功能。定时器与计数器在本质上是一样的,都是记录信号(通常为脉冲信号)的个数。当计数脉冲是稳频信号时,计数器可以记录时间间隔,即用作定时器,因此定时器实际上是一种特殊的计数器。计数器通常按二进制计数,计数范围由二进制数的位数确定。MCS-51计数器的初始值由软件来设置,加法计数,计数超过计数范围的情况,称为溢出。此时相应的溢出标志置1,可供查询或向CPU产生中断请求。定时器/计数器的工作方式由程序来设置,当它工作在定时方式时,计数脉冲来自单片机内部;当它工作在计数方式时,计数脉冲来自外部。7.2MCS-51定时器结构8051有2个16位的计数器(其中计数器1由TH1和TL1组成,计数器0由TH0和TL0组成)。计数器的工作都由特殊功能寄存器TMOD和TCON所控制。当作为定时器使用时,输入的时钟脉冲是由晶体振荡器的输出经12分频后得到的,即每个机器周期使计数器的数值加1。当用作对外部事件计数时,计数脉冲来自输入引脚T0(P3.4)或T1(P3.5),最高计数频率为晶振频率的1/24。定时器/计数器结构图80511TH1TL0TH0TLTMODTCON1T0T)1(T5.3P)T(P04.37.3与计数器有关的特殊功能寄存器与计数器有关的特殊功能寄存器有3个:TMOD,TCON,IE工作模式寄存器—TMOD(89H)TMOD用于控制计数器0和计数器1的工作模式,其各位的定义:M0M1GATEM0M1GATED0D1D2D3D4D5D6D7TC/TC/其中,高4位用于计数器1。低4位用于计数器0。TMOD(89H)不能位寻址,只能字节寻址。工作模式00—模式001—模式110—模式211—模式3方式选择1—计数方式,计数片外脉冲(即对来自P3.4/P3.5的计数信号计数,周期不定)0—定时方式,计数片内脉冲(即对机器周期计数,周期确定)选通控制1—受/INT0//INT1控制,只有INT0/INT1输入信号为高电平,软件使TR0/TR1置1,才可启动定时器0—不受/INT0//INT1控制,软件使TR0/TR1置1,即可启动定时器GATEC/TM1M0控制寄存器—TCON(88H)TCON各位的作用如下:TF1(TCON.7)——计数器1溢出标志位。溢出1,未溢出0TF0(TCON.5)——计数器0溢出标志位。供查询或产生中断请求TR1(TCON.6)——计数器1运行控制位。1启动计数,0禁止计数TR0(TCON.4)——计数器0运行控制位。IE1,IT1,IE0和IT0——外部中断INT1,INT0请求及其触发方式控制位。0AFH0AEH0ADH0ACH0ABH0AAH0A9H0A8HEA//ESET1EX1ET0EX0中断允许控制寄存器(IE)ET1,ET0是定时器中断允许位。7.4定时器/计数器的工作方式MCS-51的定时器/计数器共有四种工作方式。工作在方式0、方式1和方式2时,定时器/计数器0和定时器/计数器1的工作原理完全一样,现以定时器/计数器0为例介绍前三种工作方式。M1M0工作模式功能描述00模式013位计数器01模式116位计数器10模式2可自动重置初值的8位计数器11模式3定时器0:分成两个8位计数器定时器1:停止计数模式0(M1M0=00):13位计数方式,其计数器由TH0全部8位和TL0的低5位构成。定时器0模式0结构如图所示。C/T=0时,控制开关接通振荡器12分频输出端,对机器周期计数。这就是定时工作方式。定时时间为t=(213–T0初值)×振荡周期×12用于计数工作方式时,计数长度为213=8192(个外部脉冲)。模式1(M1M0=01):16位的定时器/计数器。其结构与操作几乎与模式0完全相同,唯一的差别是:在模式1中,寄存器TH0和TL0是以全部16位参与计数操作。用于定时工作方式时,定时时间为:t=(216–初值)×振荡周期×12用于计数工作方式时,计数长度为216=65536(个外部脉冲)。模式2(M1M0=10):可以自动重置初值的8位定时器/计数器。TL0计数溢出时,不仅使溢出中断标志位TF0置1,而且还自动把TH0中的内容重新装载到TL0中。这里,16位计数器被拆成二个,TL0用作8位计数器,TH0用以保护初值。•用于定时工作模式时,其定时时间为t=(28-初值)×振荡周期×12•用于计数工作方式时,最大计数长度(TH0初值=0)为28=256(个外部脉冲)•这种工作模式可省去用户软件中重装常数的语句,并可产生相当精确的定时时间,特别适于串行口波特率发生器。模式3(M1M0=11):仅计数器0可用在模式3,TL0和TH0被分成为两个相互独立的8位计数器。TL0使用计数器0的各控制位、引脚和中断源,其操作模式和模式0、1相同。TH0用于简单的内部定时,它占用定时器T1的控制位TR1和TF1,其启动和关闭仅受TR1的控制。TH0仅占用中断允许寄存器IE中与计数器1中断有关的位,但并未占用TMOD中的位,TMOD中的定时器1的控制位仍然由计数器1使用。定时器1无工作模式3,若定时器1设置为模式3,就会立即停止计数。在定时器0用作模式3时,定时器1仍可设置为模式0~2,由于TR1和TF1被定时器0占用,计数器控制开关已被接通,此时,仅用计数器1控制位C/T切换其定时器或计数器工作方式就可使计数器1运行。计数器1(8位、13位或16位)溢出时,只能将输出送入串行口或用于不需要中断的场合。一般情况下,当定时器1用作串行口波特率发生器时,定时器0才设置为工作模式3。此时,常把定时器1设置为模式2,用作波特率发生器。模式3(续)小结1.定时器/计数器在各种工作方式下的最大计数和最长定时时间(1)最大计数值模式0:213=8192模式1:216=65536模式2、3:28=256(2)最长定时设晶振频率fosc=6MHz,则一个机器周期t=12/6MHz=2μs模式0:Tmax=213×t=16.384ms模式1:Tmax=216×t=131.072ms模式2、3:Tmax=28×t=0.512ms2.初值计算(1)作计数器时初值=最大计数值-计数个数(2)作定时器时初值=最大计数值-(定时时间/机器周期)7.5定时器/计数器应用举例【例7-1】对定时器1编程,产生一个50Hz的方波,由P1.1输出。使用程序查询方式,设fosc=12MHz。解:方波周期T=1/50Hz=0.02s=20ms,则定时时间为10ms,因为fosc=12MHz,所以,机器周期为1μs计数初值=216-10×1000/1=65536-10000=55536=D8F0H源程序如下:MOVTMOD,#10H;计数器1工作在模式1,定时方式SETBTR1;启动计数器1LOOP:MOVTH1,#0D8H;装入计数初值MOVTL1,#0F0HJNBTF1,$;计数器1没有溢出,等待CLRTF1;产生溢出,清标志位CPLP1.1;P1.1取反,输出SJMPLOOP;循环【例7-2】设单片机的晶振频率fosc=12MHz时,用定时器T0定时1ms,从P1.0引脚输出周期为2ms的方波脉冲。通过查询T0的溢出标志位TF0,判断定时时间到与否,具体程序如下:ORG0100H;主程序入口MAIN:MOVTMOD,#00H;T0设为方式0,软件启动定时MOVTL0,#18H;初值写入T0MOVTH0,#0E0HSETBTR0;软件启动T0定时工作LOOP:JBCTF0,PV;查询溢出标志,若TF=1,则TF清0并转移SJMPLOOP;1ms定时时间未到,等待PV:CPLP1.0;1ms定时时间到,P1.0输出信号取反,形成方波MOVTL0,#18H;重新装入初值MOVTH0,#0E0HSJMPLOOP也可以用中断方式编程,具体程序如下:ORG0000H;MCS-51复位入口AJMPMAIN;转入主程序ORG000BH;T0中断入口地址AJMPINT_T0;转入中断服务程序ORG0100H;主程序入口MAIN:MOVSP,#40H;设置堆栈MOVTMOD,#01H;T0设为方式1,软件启动定时MOVTL0,#18H;初值写入T0MOVTH0,#0FCHSETBET0;允许T0中断SETBEA;开放总中断SETBTR0;启动T0定时工作HERE:SJMPHERE;原地踏步(处理其它事务)等待中断到来ORG0200H;中断服务程序INT_T0:CPLP1.0MOVTL0,#18H;初值写入T0MOVTH0,#0FCHRETI;中断返回END【例7-3】记录T0(P3.4)引脚上的脉冲数,记满100个脉冲,从P1.0输出一个正脉冲脉冲。请编程实现该功能。解:首先选计数器0为模式2,外部事件计数方式。计数初值为256-100=156=9CH源程序如下:START:MOVTMOD,#06H;设置计数器0为模式2。外部计数方式MOVTH0,#9CH;计数器0初值MOVTL0,#9CHCLRP1.0;初始化P1.0=0SETBTR0;启动计数器0LOOP:JBCTF0,L1;查询溢出标志,TF0=1时转移SJMPLOOP;TF0=0时,等待L1:CPLP1.0;利用取反指令,输出脉冲前沿NOPCPLP1.0;利用取反指令,输出脉冲后沿LJMPSTART【例7-3】记录T0(P3.4)引脚上的脉冲数,记满100个脉冲,从P1.0输出一个正脉冲脉冲。用中断方式编程实现该功能。解:源程序如下:ORG0000HLJMPSTARTORG000BHLJMPINT_T0ORG0030HSTART:MOVTMOD,#06H;设置计数器0为模式2。外部计数方式MOVTH0,#9CH;计数器0初值MOVTL0,#9CHCLRP1.0;初始化P1.0SETBET0;中断允许SETBEASETBTR0;启动计数器0SJMP$;等待INT_T0:CPLP1.0;利用取反指令,输出脉冲前沿NOPCPLP1.0;利用取反指令,输出脉冲后沿RETIEND本章结束