【C51】单片机定时器介绍

时间:2020-12-06 23:35:42

标准51架构的单片机有2个定时器 :T0  和  T1,他们2个的用法几乎一样。下面主要讲T0定时器的用法。

 

初步认知

【C51】单片机定时器介绍

 

定时器 和 计数器 都是单片机中同一个模块。他们的实质都是: 加法存储计数器。对于计数器很好理解,每来一个信号(信号从P3.4 或者P3.5输入),就加1,以此达到计数的目的。 对于定时器,每隔1个机器周期 加 1,假如(只是假如)一个机器周期为 1ms , 当加到1000时,我们就认为经过了1s,这就是定时器的原理。

 

加法存储寄存器THx & TLx

  定时器依赖计数,需要把累计增加的那个量存储在某个地方,这就是THx和TLx(x 可以是 0 或者1)2个8位寄存器的的职责。 T0和T1都拥有一对加法存储寄存器。 T0 对应:TH0,TL0 T1 对应 : TH1 , TL1   在reg51.h头文件中我们发现这4个寄存器的定义:  
sfr TL0  = 0x8A;              //  TL中的L是LOW的意思,代表低位,同理H代表HIGH高位。
sfr TL1 = 0x8B;
sfr TH0
= 0x8C;
sfr TH1
= 0x8D;

 

他们可以在程序中直接使用,复位值都是 0 。 当一直累加,使得他们保存不了太大的数据而发生溢出时,就会引发中断(后面讲中断)。并且对应的TFx溢出标志位会置为1,(没有溢出的情况下是0)。 如果不使用中断去处理溢出这个事件,那么我们就必须通过代码指令让TFx重置为 0 ,并让THx和TLx回归初始值,准备然后进入下一轮周期的计数。    
....
if(TF0==1) //如果T0 溢出了
{
TF0
=0;
//重新初始化 TH0 和 TL0
//说明过了一个溢出周期了
}

 

 

 2个重要的寄存器:TMOD 和 TCON

    【C51】单片机定时器介绍

 

复位时所有位全  为 0

TFx:溢出标志位。溢出时置1。正常为0。 TRx:计数器/定时器 启动停止控制位 。R是run的意思。  TR0 = 1  开启定时器0,为TR0 = 0 则停止。  低4位与外部中断相关,这里用不到,先不用看。

 

 

 

【C51】单片机定时器介绍

 

 

复位时所有位全  为 0

高4位是定时器T1相关的,低4位是T0 相关的。以T0来说明。  GATE:      门控制位C/T    :     定时器/计数器切换位。 1为计数器模式, 0 为定时器模式。

 

【C51】单片机定时器介绍

②处 C/T = 0 表示为定时器模式,触发信号为①处的单片机内部时钟信号。(若②处CT = 1,则触发信号为Tn脚,信号从P3.4 或者P3.5输入单片机) ③处表明,信号能触发使加法计数器加1,还得受④处控制。不然时钟信号是不能让加法计数器累加的。 ④处这个是与门,TRn必须为1,表明我们要开启定时器。同时GATE为0,通过非门后为1,再通过或门,也是1,那么就让③处控制起来了。 (若GATE为1,那么,定时器的启动停止受 TRx和 INTx 共同控制。 )  于是我们需要:TRn    为 1GATE  为 0INTn   为 X(X表示任意的意思,do not care)    加法存储寄存器的工作模式,是由M0和M1共同来决定的
M1 M0 模式
0 1 TH和TL2个组成16位计数存储器模式
1 0 TH负责初始化TL,TL计数。8位重装模式
0 0 THx的8位和TLx的位5组成13位加法计数器(很少用)
1 1 基本不用

 

 

 

时钟周期和机器周期

 
顺便提一下:标准C51的1个机器周期为12个时钟周期(增强型51单片机的机器周期会短一些,cc2530只有的机器周期只等于1个时钟周期)。如果晶振的频率是11.0592MHz,那么时钟周期就是   1 / (11.0592x10^6) 秒   (1MHz = 10^6Hz)

那么,无论是定时器,还是计数器,每隔1个机器周期 ,加法存储器就1,代表时间经过了  12  x     1 / (11.0592x10^6) 秒。这就是我们衡量的基础依据。

  

为THx和TLx赋初始值

若TH0 和 TL0 以 16位 模式工作,那它的计数范围为   [0 , 65535 ]  ,  也就是累加 65536次发生溢出。 每累加一次是  12 / (11.0592x10^6) 秒。 那么从 0 累加到溢出 历时  ≈ 0.071s = 71ms 。 我们一般需要延时 10的整数倍ms,以便用倍数控制更长的延时时间。所以,我么要给 TH0 和  TL0赋一个初始值,使他们的溢出周期(TH0,TL0从初始值到溢出所用的时间)减少到 10ms,或者1ms。 就像一个瓶子,开始装了2/3,再来就只能装1/3就溢出了。  

 12 / (11.0592x10^6) s       -----     1   次

  10x 10-3   s                        ------          x  次         (求出 x = 9216次 ,计数9216次后溢出)
  65536 - 9216 = 56320  =  二进制( 11011100   00000000)   也就是  TH0 = 11011100 , TL0 = 00000000

 

 

代码例子验证

 

#include<reg51.h>
typedef unsigned
int uint;


/**************函数声明******************/
void delay10ms(uint m) ;
void delay1ms(uint m) ;
/********************************/


/*****************************/
sbit LED
= P0^0;
/*****************************/



void main()
{
while(1)
{
LED
= 1;
delay10ms(
100); // delay1ms(1000)
LED = 0;
delay10ms(
100); // delay1ms(1000)


}
}


void delay10ms(uint m) //溢出周期为10ms
{

/********************
使用到的寄存器(位)

TH0 TL0

TCON: TR0 TF0
TMOD:

**********************
*/



uint count =0;
TMOD
= 1; //GATE = 0 C/T =0 M1 = 0 M0 = 1; 16位计数器
TL0 = 0 ;
TH0
=220 ;

TR0
= 1;

for(;count<m;)
{
if(TF0 == 1)
{
TF0
= 0;
TL0
= 0;
TH0
= 220;

++count;

}
}

TR0
= 0; //关闭定时器

}



void delay1ms(uint m) //溢出周期为1ms
{
uint count=0;
TMOD
= 1; //计时器0以16为存储计时器工作
TH0 = 252 ;
TL0
= 102;
TR0
= 1;

for(;count<m;)
{

if(TF0==1) //发生一次溢出,也就是过了1ms
{
TF0
=0; //溢出位清零,取消警报
TH0 = 252 ; //重新配置初始值
TL0 = 102;
count
++; //溢出次数加1 ,溢出1次是1ms,溢出t次就是t ms
}


}

TR0
= 0;

}

 

 

 

8位重装模式

8位重装模式是:只有TL0计数,TH0不变,他只为TL0提供初始值。当TL计数溢出后,TF0就为1,如果继续工作,TH0就把自己的值赋给TL0,再开始计数,如此循环下去。

上面些写了一个毫秒级的delay函数,下面用8位重装模式写一个控制微秒级别的函数。并控制P0.0的LED实现呼吸灯。

 

计算方法和上面一样,大家可以自己算

 

#include<reg51.h>
typedef unsigned
int uint;


# define TRUE
1
# define FALSE
0

/**************函数声明******************/
void
delay1ms(uint t);/********************************/

sbit LED
= P0^0;


void main()
{

int step = 0;
int again = FALSE;

while(1)
{

LED
= again?0:1;
delay1ms(step);

LED
= again?1:0;;
delay1ms((
500-step));

step
+=1;

if(step>500)
{
step
=0;
again
= !again;
}

}

}


void delay1ms(uint m) //延时t微秒
{
int count=0;
TMOD
= 2;
TH0
= 255 ;
TL0
= 255;
TR0
=1;

for(;count!=m;)
{

if(TF0==1)
{
TF0
=0; //自动重装
count++;
}

}
TR0
=0;

}

 

 

值得注意的地方

我们应该尽量让溢出周期 越长越好。溢出周期为10ms 的优于 1ms 的。因为,在同样的延时时间下,如100ms,溢出周期为10ms 的 只需要溢出10次,为TH0 和 TL0重新赋值10次,而溢出周期为1ms的要溢出100次,为TH0 和 TL0重新赋值100次。减少溢出次数和赋值次数,可以减轻单片机的负担,提高定时的准确性。

【C51】单片机定时器介绍

 

 

 

/***************************************************/

 欢迎转载,请注明出处:www.cnblogs.com/lulipro

 为了获得更好的阅读体验,请访问原博客地址。

 代码钢琴家

/***************************************************/