一.基本设置

一般而言,即使只是使用定时器而不用中断功能,也需要设置3步:

1.启动定时/计数器:在TCON中令TR0/TR1=1
2.设置定时/计数器如何工作:给TMOD赋值(16进制数)
3.给定时/计数器写入初始值:根据计数次数,分别给高8位TH0/1、低8位TL0/1赋值

如果需要使用中断,则还需要:
4.允许中断:在IE中打开总允许位(EA)和定时器中断允许位(ET0、ET1)

二.设置初始值的问题

若工作在计数模式,则很容易设:若设需要计次N,则初值X=(2^16-N)+1。

如果是定时模式,就要计算需要定多长时间。由前,单片机CPU内部时钟信号的频率如果是1MHz,则机器周期为1us。也就是说,如果要定时1ms,则需要1000个机器周期;而时钟每输入一次脉冲(定时器加1),就经历了一个机器周期的时间。因此,如果要定出1ms,则需要计数1000次。若以工作方式1(16位为满)为例,则初值应该是(2^16)-1000+1。再把它转化为16进制数字就是0xFC18,分别填入高、低8位里。
注意:最后的初值要加1。因为定时器计满了以后,还要再加1才会归零。否则,最后将会计数1001次。
如果需要定时1s,可以通过定时1000个1ms来实现。

三.程序实例

还是和前面一样,如果要使用定时器中断,程序中至少要包含那三个模块;如果只是单单设置、使用定时/计数器,也可以把定时器的设置单独作为一个模块。

1.编写程序,让LED灯在1s的间隔内跳跃闪动
代码如下:

#include <stdio.h>
#include <reg52.h>

sbit led = P2^1;

void Init_T0()  //定时器初始化、开启中断
{
  TR0=1;		    //开启定时/计数器0
 
  //中断所需时间为1ms,也就是计次1000次,故定时器初值为(2^16-1000+1),转换为16进制数就是0xFC18H,分别把它们填入高、低八位
  TH0=0xFC;		
  TL0=0x18;	    
  
  //TMOD赋值,设置工作方式:GATE=0,定时器模式(0),工作方式1
  TMOD=0x01;
   
   //允许中断
  EA=1;           
  ET0=1;
}

void main()
{
 Init_T0();
 while(1);
}

void Timer_0() interrupt 1
{
 //设置变量i,计算中断次数。累计1000次中断后,就可以定出1s
 static int i=0;
  i++;
  
  //必须注意!这里进入中断服务函数后,还要再填一次初值,让它保持原来那样计数
  TH0=0xFC;       
  TL0=0x18;
 
 //中断1000次后,达到1s,LED灯取反
 if(i==1000)
 {
 i=0;
 led=~led;
 } 
}