51单片机定时器使用


单片机的几个周期:
  1. 时钟周期,也称为振荡周期:定义为时钟脉冲的倒数,在单片机中也就等于晶振的倒数。

    51单片机中把一个时钟周期定义为一个节拍(用P表示),2个节拍定义为状态周期(用S表示)。

    时钟周期是单片机中最小的时间单位。

    例如:12M晶振的单片机,时钟周期=振荡周期=1/12 us。

  2. 机器周期:定义为完成一项基本操作所需要的时间,称为机器周期。 在计算机中,为了方便管理,把一条指令的执行过程分为若干个阶段,每个阶段去执行一项基本操作。

    如:取指令,存储器读,存储器写等。

  3. 指令周期:定义为执行一条指令所需的时间。 通常,包含一个机器周期的指令称为单周期指令,比如 MOV指令,CLR指令等,还包含两个机器周期的指令称为双周期指令,另外还有四周期指令。

51单片机的定时器时间的计算

1Hz:1秒内电流往返一次

晶振:11.0592 MHz =11059200 Hz

时钟周期:1/11059200 s(晶振的倒数)

机器周期:12/11059200 s (标准框架下51单片机一个机器是12个时钟周期)

因为定时器是每个机器周期加1所以定时时间为 N*时钟机器周期时间=所定时间T

所以要经过的机器周期是:

N*(12/11059200 s)=T

即:N=t/(12/11059200)

初值等于 65536-N(因为16位的定时器65535再加1才溢出)

例如:

需要定时 20ms=0.02s

N = 0.02/(12/11059200) = 18432

初值y=65536-18432=47104=0XB800

51单片机的定时器时间的使用

  • 第一:设置特殊功能寄存器TMOD,配置好工作模式。

  • 第二:设置计数寄存器TH0和TL0的初值。

  • 第三:设置TCON,通过TR0置1来让定时器开始计数。

  • 第四:判断TCON寄存器的TF0位,监测定时器溢出情况。

下面我们用一个简单的例子实现跑马灯实验,间隔为1 s!

# include <8052.h>

# define ADDR0 P1_0
# define ADDR1 P1_1
# define ADDR2 P1_2
# define ADDR3 P1_3
# define ENLED P1_4

void main() {

    unsigned char cnt = 0;      //定义一个计数变量,记录T0溢出次数
    unsigned char i = 0;

    ENLED = 0;                  //使能U3,选择独立LED
    ADDR3 = 1;
    ADDR2 = 1;
    ADDR1 = 1;
    ADDR0 = 0;

    TMOD = 0x01;                //设置T0为模式1,对照表格即为定时器/计数器的4种模式中的16位定时器/计数器模式
    TH0 = 0xB8;                 //为T0赋初值0xB800
    TL0 = 0x00;

    TR0 = 1;


    while(1) {
        if (TF0 ==1 ) {         //判断T0是否溢出
            TF0 = 0;            //T0溢出后,清零中断标志
            TH0 = 0xB8;         //并重新赋初值
            TL0 = 0x00;

            cnt ++;             //计数值自加1

            if (cnt >= 50) {    //判断T0溢出是否达到50次
                cnt = 0;        //达到50次后计数值清零


                P0 = ~(0x01<<i);//下面是跑马灯
                i++;
                if (i >= 8) {
                    i = 0;
                }
            }
        }
    }
}