定时器/计数器是一种计数装置,若对内部时钟脉冲计数,可视为定时器;若对外部时钟脉冲计数,可视为计数器。
定时器/计数器的应用可以采用中断的方式当定时或计数达到时产生中断,另外也可以采用询问的方式,不断询问计数状态,以控制程序流程。
8051计数寄存器是THx和TLx两个8位的寄存器,x=1或x=0。
8051的定时器/计数器8051单片机有2个16位定时器/计数器:定时器0(Timer0)和定时器1(Timer1)简称T0和T1,8052在包含了T0、T1还有一个Timer 2(T2)。这三个定时器/计数器都可作为内部定时器或外部计数器。
若是作为内部定时器时,是计数内部的脉冲。以12MHz的计数时钟脉冲系统为例,将12MHz/12送入定时器,此时定时器所计数的脉冲周期为1us。若采用16位的定时模式,则最多可计数65536个脉冲(即2^16),约0.0655s。
若作为外部计数器时,则是计数由T0或T1引脚送入的脉冲。同样的,若采用16位的定时模式,最多可计数65536(即2^16)个计数量。
定时器/计数器模式寄存器TMOD定时器/计数器模式寄存器TMOD主要设定定时器/计数器的工作模式、计数信号来源及启动方式等。
TMOD模式寄存器的低四位T0(0-3)配置定时器/计数器0(Timer0)的工作模式,高四位T1(4-7)配置定时器/计数器1(Timer1)的工作模式,这两部分的结构类似,只是控制的对象不同。
我们以高四位为例来了解TMOD模式寄存器的使用,即使用T 1,(T0一样的用法):
GATE为Timer的门控开关,用来决定Timer 1(T 1)的启动方式。
若GATE = 0,则只要 TR1 = 1,即可启动Timer 1,称为内部启动或软件启动;
若GATE = 1,则需要 TR1 = 1,还要等待外部中断引脚INT1为高电平,Timer 1才能启动工作,称为外部启动或硬件启动。
C/T(Count/Timer)定时器/计数器切换开关:C/T=0为内部定时器,用来计数OSC/12的脉冲;C/T=1为外部计数模式,用来计数由T 1(P3.5)引脚输入的脉冲;
M0,M1定时/计数模式选择开关:
Mode0(M1 = 0,M0 = 0):
提供两个13位定时器/计数器(Timer 0/Timer 1),如前所述,计数量分别存放在TH1和TL1两个8位计数寄存器里。其中TH1放置8位,TL1放置5。
如前所述,若要执行定时功能,则C/T设定为0,计数内部脉冲;若要执行计数功能,设置C/T为1,计数外部脉冲信号。
启动方式为外部启动时:设定GATE = 1,TR1=1,再等待外部中断引脚INT1输入高电平,即可启动 Timer 1;
启动方式为内部启动时:设定GATE = 0,TR1=1,即可启动 Timer 1;
Mode1(M1 = 0,M0 = 1):
提供两个16位定时/计数器,计数量分别存放在THx和TLx两个8位计数寄存器里。
Mode 1下的定时器/计数器的工作模式切换、启动方式等与Mode 0 完全一样,Mode 1计数量更大,所以完全可以替代Mode 0。
Mode 2(M1 = 1,M0 = 0):
提供两个8位可自动加载的定时器/计数器(Timer 0和 Timer 1),其计数寄存器里的计数量放置在TLx里,当改定时器/计数器中断时,会自动将THx计数寄存器里的计数量载入到TLx里。由于计数只用了8位,所以其最大计数为256。
Mode 2下的定时器/计数器的工作模式切换、启动方式等与Mode 0 完全一样。
Mode 3(M1 = 1,M0 = 1):
此工作模式是一种特殊的模式,提供一个8位的定时器/计数器 Timer 0和一个8位的定时器Timer 1。
其中Timer 0除了不具有自动加载功能外,与Mode 2的Timer0几乎完全一样。
而Timer 1定时器也几乎可以被Mode 2的Timer 1所取代。
定时器/计数器控制寄存器TCON寄存器TCON的高四位一共定时器/计数器的启动开关和中断时的标志位,低四位为外部中断触发控制位和外部中断请求标志位,如下图:
TF1:定时器Timer 1中断(溢出)标志位。当Timer 1时,由硬件自动设定TF1= 1,并向CPU申请中断。Timer 1中断结束时,CPU自动对TF1清零。TF1也可以用软件清零。
TR1:定时器Timer 1启动开关。TR=1,Timer 1启动,TR1=0关闭Timer 1。
TF0:定时器T0溢出标志位。其功能与TF1相同。
TR0:定时器T0运行控制位。其功能与TR1相同。
IE1:外部中断1(INT1)标志位。
IT1:外部中断1(INT1)触发方式控制位。
IE0:外部中断0(INT0)标志位。
IT0:外部中断0(INT0)触发方式控制位。
计数寄存器:8051的计数寄存器是THx和TLx两个8位寄存器,除了Mode 3之外,TH0和TL0是Timer 0所使用的计数寄存器,TH1和TL1是Timer 1所使用的的计数寄存器。若是8052还有Timer 2所使用的TH2和TL2。
8051定时器/计数器是一种正数计数器。当计数到满(溢出)时,即产生中断。我们计数时用该模式下的最大计数量减去所需计数,即从终点往前推,比如最大计数量为100,需要计数40,则从60处开始计数。
不同模式下的最大计数量不同,设定方式也有差异。
下面对各个模式下计数寄存器分别做说明:
Mode 0
由于Mode 0 TLx计数寄存器只使用5位,2^5 = 32,我们要把计数起点的值除以32,其余数放入TLx计数寄存器;其商放入THx计数寄存器。例如要使用Timer 0计数6000,则:
TL0 = (8192 - 6000)% 32;//取低5位
TH0 = (8192 - 6000)/ 32;//取高8位
Mode 1
在此模式下,TLx和THx计数寄存器都是8位,而2^8=256,同样使用Timer 0计数6000则
TL0 = (65536 - 6000)% 256;
TH0 = (65536 - 6000)/ 256;
Mode 3
在此模式下,使用TL0计数寄存器作为第一个定时器/计数器的计数量,而TH0计数寄存器作为第二个定时器的计数量,用到哪个就填入哪个。两个都用到就对TL0、TH0分别填入对应的值。填入方法与Mode 2一样。
定时器/计数器的使用定时器/计数器有两种使用方式:中断和查询
中断:包括定时器/计数器中断的设定、计数量的设定、启动设定及中断子程序的编写
查询:只要设定计数量及启动,然后判断定时器/计数器的标志位(TFx)是否动作,接着程序流程的跳转。
中断设定(关于8051的中断就不展开了):
中断的设定包括开启开关(IE寄存器的设定)、中断优先级的设定(即IP寄存器的设定)、中断信号的设定(TCON寄存器的设定)等。例如要开启中断总开关及T0开关(IE为中断启用寄存器,IP为中断优先级寄存器):
IE=0x82;//打开中断总开关及启用T0中断
把T0中断设定高优先级,并设定为内部定时器,软件启动方式,采用Mode 1:
IP=0x02;//T0中断高优先级
TMOD = 0x01;//设定为内部定时器、软件启动和Mode 1
计数量设定(略,见上文)
定时器/计数器启动
TRx=1;// 启动Timer x
中断子程序
中断程序格式:void 函数名 interrupt 数字0—5
0 外部中断INT0
1 定时器/计数器TF0
2外部中断INT1
3定时器/计数器TF1
4串行口TI/RI
5定时器/计数器TF2/EXF2(8052才有)
注意区分定时器/计数器的中断编号与外部中断编号,定时器 0的中断编号为 1,定时器 1的中断编号为 3,定时器 2的中断编号为 5。
如:
void my_INT (void) interrupt 3 //Timer 1溢出中断子程序
{
…….//中断子程序逻辑代码
}