一、定时器的结构以及工作原理
MCS-51单片机内部有两个16位可编程定时器/计数器,即定时器T0和定时器T1。他们既可以用作定时器的方式,又可以用作计数器的方式,共4种不同的工作方式
寄存器TMOD用于控制T0和T1的工作方式,可通过编程设置TMOD来决定工作方式。
CATE C/T M1 M0 GATE C/T M1 M0
M1M0为工作方式控制位,我们常用工作方式1,若要设置T0以“方式1”工作,可使用TMOD=0X01;来设置。
定时/计数器的核心是16位加法计数器,T0的加法计数器由两个8位寄存器TH0,TL0构成,TH0表示加法计数器的高八位。TL0表示加法计数器的低八位,TH1、TL1则表示定时/计数器T1的假发计数器的高八位和低八位。
当16位加法计数器的输入端每输入一个脉冲,16位加法计数器的值自动加1,当计数器的计数值超过加法计数器字长所能表示的范围而溢出时,CPU申请中断,若允许中断,则CPU停下当前执行的程序,转去执行中断程序,中断程序执行完后,继续执行原来的程序。
二、定时器使用的一般步骤
1、设置工作方式TMOD=0X01;
2、计算初值,并且将初值装入TL0、TH0
TH0=(65535-50000)/256;TL0=(65535-50000)%6;
3、设置EA=1;开总中断允许开关
4、设置ET0=1,开定时器0中断允许
5、设置TR0=1,启动定时
6、编写中断程序
三、初值的计算
在工作方式1的前提下,计数的范围从0到65535,经过六万多次的计数后,才会产生溢出。可我们在实际运用的时候,常常不需要那么多的计数,那么该怎么办呢?
单片机的16位计数器,就像一只空的水桶,向其中滴65535滴水后,就会发生溢出,如果我们希望在滴100滴水后,就让它溢出,我们可以一次性的相这只水桶中先放入65535-100即65435滴水,然后再一滴一滴地计数,这样,就达到了调用100滴水就溢出的目的了。
当定时器、计数器工作于定时状态的时候,对机器周期进行计数,若定时时间为t,则对应的计时次数N=t/机器周期
例如:利用定时器0,在工作方式1下,控制发光二极管每50MS闪烁一次
#includesbit D=P1^0;void main(){ TMOD=0X01; TH0=(65535-50000)/256; TL0=(65535-50000)%6; EA=1; ET0=1; TR0=1; while(1);}void T0_PRG interrupt 1{ TH0=(65535-50000)/256; TL0=(65535-50000)%6; D=~D;}
四、长计时
51单片机定时、计数器的最大计数容量是65535,换算成时间,也就65ms左右。
在实际生产、生活中,定时的长度往往是秒级的,甚至是分钟、小时,以至于更长时间,MCS-51 的定时、计数器最长定时只有65MS左右,这显然实用性不强,为了解决这个问题,一般有两种途径,即“硬件法”和“软件法”,“硬件法”是通过使用专用的芯片来完成长定时。而“软件法”只需要在程序里运用一些小技巧就可以,尽管这种方法实现定时的精度没有硬件方式高,但因为简单并不增加成本,所以精度要求不很高的情况下,是非常适合的。
既然MCS-51的定时、计数器最长定时只有65ms左右,那么我们就先让它定时50ms,在定时、计数器产生溢出时并不去执行我们要做的动作,而是给一个变量加1,这样反复做定时,当变量值为20时,也就是说定时、计数器溢出20次的时候,才执行我们要做的工作,50msX20=1000ms 即1秒。那么 2秒、10秒,更长的定时,只需要更改反复溢出的次数,就可以轻松解决。改进后的程序如下:
#includesbit D=P1^0;unsigned char n;void main(){ TMOD=0X01; TH0=(65535-50000)/256; TL0=(65535-50000)%6; EA=1; ET0=1; TR0=1; while(1);}void T0_PRG interrupt 1{ TH0=(65535-50000)/256; TL0=(65535-50000)%6; n++; if(n==20) { n=0; D=~D; } }