在使用单片机进行LED闪烁的时候,我们可以加入一段延时代码来让LED灯亮和灭持续一段时间,但这种方法既无法精确的控制时间也浪费CPU资源。这时候单片机内的定时器就派上用场了。

基础介绍

单片机中有2个定时器/计数器,每个定时器/计数器由2个8位寄存器组成,以定时器/计数器T0为例,高8位寄存器为TH0,低8位寄存器为TL0;同理,定时器/计数器T1的高8位寄存器为TH1,低8位寄存器为TL1。

单片机的定时器/计数器其实就是加1计数器,当脉冲来的时候就往寄存器里加1,寄存器一共16位,加满了就会溢出,这时溢出标志位TF0/TF1就会为1,我们通过判断溢出标志位或者通过溢出引起中断就能实现想要的功能。如果这个脉冲是来自单片机自己的时钟脉冲,那么这就是一个定时器;如果这个脉冲来自外部(T0、T1脚),那么这就是计数器。

我们可以通过设置TMOD寄存器(定时器/计数器工作方式寄存器)和TCON寄存器(定时器/计数器控制寄存器)来启动定时器/计数器。

以下是这两个寄存器的详细介绍:

定时器/计数器工作方式寄存器TMOD

定时器/计数器工作方式寄存器TMOD

TMOD的高四位和低四位分别控制T1和T0这两个定时器/计数器。

这里的GATE是门控制位,如果GATE=0那么定时器/计数器的启动和停止就只受到TCON寄存器里的TR0或TR1控制。

C/T是用来设置模式的,当C/T=0时,它是定时器;当C/T=1时,它是计数器。

M1和M0,这两位有4种组合,这4种组合对应了4种的工作方式:

定时器工作方式

定时器/计数器控制寄存器TCON

定时器/计数器控制寄存器TCON

其中高4位是用于定时器/计数器的,我们主要来看下这4个。

TF1:定时器1中断(溢出)标志位。当定时器/计数器1(T1)计满的时候,它就会为1。

TR1:定时器1启动控制位。当GATE=0时,TR1=1启动定时器1,TR1=0关闭定时器1。

TF0的作用与TF1类似,TR0的作用与TR1类似,只不过TF0、TR0是用来控制定时器0的。

定时器开启后就会一直加1,直到溢出。我们要让它定我们想要的时间,就要先装入初始的数值,这样才能好计算。定时器初值的计算公式是:

定时器初值计算公式

其中定时时间T的单位是微秒,单片机晶振频率的单位是MHz,N是定时器的工作方式:方式0时N为13,方式1时N为16,方式2时N为8。

比如我们要定的时间是1000微秒,单片机晶振频率是12MHz,采用工作方式1,那么就可以列出这个式子:1000=[12*(2^16-x)]/12

解方程可得x=64536,转成十六进制就是FC18,这就是我们要加入的初值。

具体使用

下面我们就以一个例子来看看定时器的具体使用。

要实现的功能:一个晶振为12MHz的单片机P1.0脚接一个LED灯,控制其一秒钟闪烁一下。

硬件电路图:

硬件电路图

软件代码:

计算初值:因为1秒等于1000000微秒,所以这里定时器时间设置成50000,这样当定时器计满20次刚好1秒。列出公式50000=[12*(2^16-x)]/12解得x=15534转十六进制为3CAE。

#include <reg51.h>
sbit LED=P1^0;
int a=0;
void main()
{
  TMOD=0x01;//使用定时器T0,高4位全为0,低4位GATE=0,C/T=0,采用工作方式1,M1=0,M1=1
  TH0=0x3c;//装入初值,高8位装3C,低8位装AE
  TL0=0xae;
  TR0=1;//启动定时器0
  while(1)
  {
    if(TF0==1)//判断定时器是否溢出
    {
      TF0=0;//清除溢出标志位
      TH0=0x3c;//重新装入初值
      TL0=0xae;
      if(a==20)//因为要1秒闪烁一次,到这里计数器计了0.05s,需要20个0.05s才有1s
      {
        LED=~LED;
        a=0;
      }else{
        a=++a;
      }
    }
  }
}

本文版权归一天天世界所有,转载请注明出处并添加本文链接。

 
返回顶部
ett