标准的 51 单片机内部有 T0 和 T1 这两个定时器,T 就是 Timer 的缩写,现在很多 51 系列单片机还会增加额外的定时器,在这里我们先讲定时器 0 和 1。前边提到过,对于单片机的每一个功能模块,都是由它的 SFR,也就是特殊功能寄存器来控制。与定时器有关的特殊功能寄存器,有以下几个,大家不需要去记忆这些寄存器的名字和作用,你只要大概知道就行,用的时候,随时可以查手册,找到每个寄存器的名字和每个寄存器所起到的作用。
使用定时器 0,在使用定时器的时候,需要以下几个步骤:
第一步:设置特殊功能寄存器 TMOD,配置好工作模式。第二步:设置计数寄存器 TH0 和 TL0 的初值。第三步:设置 TCON,通过 TR0 置 1 来让定时器开始计数。第四步:判断 TCON 寄存器的 TF0 位,监测定时器溢出情况。
在使用定时器的时候我们应用3个寄存器:
(1)TMOD定时器模式寄存器
(2)CONT定时器控制寄存器
(3)定时值存储寄存器
(1)TMOD 定时器模式寄存器(地址0x89,不可寻址):
其中: GATE C/T M1 M0
0-3为T0 3 2 1 0
4-7为T1 7 6 5 4
GATE 该位被置1时为门控位,只有当INTx=1,TRx=1时,使定时器开始计时。
该位为0时,只要TRx=1,定时器x就能开始计时,跟INTx无关。
C/T 定时器(置0)计数器(置1)切换
M1/M0 定时器模式的 4 中工作方式,其中:
0 0 模式 0: 是为了兼容老的 8048 系列单片机而设计的,现在的 51 几乎不会用到这种模式。
0 1 模式1:THn 和 TLn 组成一个 16 位的定时器,常用。
1 0 模式2:8 位自动重装模式,定时器溢出后 THn 重装到 TLn 中,常用。
1 1 模式3 :根据我的应用经验,它的功能用模式 2 完全可以取代,所以基本上也是不用的。
注意:TMOD 标注的是“不可位寻址”。意思就是说:比如 TCON 有一个位叫 TR1,我们可以在程序中直接进行 TR1 = 1 这样的操作。但对 TMOD 里的位比如(T1)M1 = 1 这样的操作就是错误的。我们要操作就必须一次操作这整个字节,也就是必须一次性对 TMOD 所有位操作,不能对其中某一位单独进行操作.
(2)CONT定时器控制寄存器(地址 0x88、可位寻址):
TF1/TF0:定时器1(0)溢出标志,一旦定时器1(0)溢出时硬件置,清零有两种方式:1.软件清零,2.进入定时器中断时硬件清零
TR1/TR0:定时器1(0)运行控制位,软件置位/清零来进行启动/停止定时器。(TR0=1 启动T0;TR1=1 启动T1)
IE1/IE0/IT1/IT0:外部中断部分,与定时器无关。
(3)定时值存储寄存器
TH0
TL0
TH1
TL1
写程序之前,要先来学会计算如何用定时器定时间:
(1)计算多少个机器周期
已知用的晶振是 11.0592M,时钟周期就是 1/11059200,机器周期是 12/11059200,
假如要定时 20ms,就是 0.02 秒,要经过x 个机器周期得到 0.02 秒,
我们来算一下需要多少个机器周期到0.02秒:x*12/11059200=0.02,得到 x= 18432。
(2)计算定时值的高低位
16 位定时器的溢出值是 65536(因 65535 再加 1 才是溢出),于是我们就可以这样操作,先给 TH0 和 TL0一个初始值,让它们经过 18432 个机器周期后刚好达到 65536,也就是溢出,溢出后可以通过检测 TF0 的值得知,就刚好是 0.02 秒。那么初值 y = 65536 - 18432 = 47104,转成 16 进制就是 0xB800,也就是 TH0 = 0xB8,TL0 = 0x00。这样 0.02 秒的定时我们就做出来了。
(3)添加一个计数,计算出需要设定的时间值
如果初值直接给一个 0x0000,一直到 65536 溢出,定时器定时值最大也就是 71ms 左右,那么想定时更长时间,用倍数关系就可以解决此问题。