51单片机定时器

under 单片机  嵌入式开发  tag     Published on December 29th , 2020 at 03:12 am

51单片机定时器工作原理

1. 模式0:13位计数器模式

在某一个初值的基础上加 1 计数,当计数器计满为全“1”,再来一个计数脉冲时,就产生一个“溢出中断信号”TF1=1。

注:由于低 8 位计数器中的高三位没有参与工作,故填装初值时应“避开”此三位。

2.模式 1:16 位定时/计数模式

类同于模式 0,由于两个计数器为完整的 8 位,故将计算好的 16 位初值可直接填装到 TH、TL 中。

3.模式2:8 位自动重装初值模式

TL 做计数器,TH 做初值寄存器,工作前 TL1,TH1 分别预置相同的初值,TL1 计数时,产生溢出的同时,将 TH1 中的初值自动重装 TL1,TL1 继续计数。

4.模式 3:组合扩展模式(仅适用于 T0)

将 T0 和 T1 重新进行“拆分、组合”,将 T0 变为由 TH0,TL0 组成的两个独立的 8 位定时/计数器。

四种模式比较

工作方式0:13位定时器/计数器工作模式,最多可计数2的13次方次,即:8192次

工作方式1:16位定时器/计数器工作模式,最多可计数2的16次方次,即:65536次

工作方式2:8位定时器/计数器工作模式,最多可计数2的8次方次,即:256次

工作方式3:8位定时器/计数器工作模式,最多可计数2的8次方次,即:256次

定时器初值

以12M晶振为例:每秒钟可以执行1000000次机器周期个机器周期。而定时器每次溢出 最多65536 个机器周期。

那么对12MHz的晶振来讲

1个机器周期 1us ( 12/fosc = 1us)

方式0 13位定时器最大时间间隔 = 2^13 = 8.192ms

方式1 16位定时器最大时间间隔 = 2^16 = 65.536ms

方式2 8位定时器最大时间间隔 = 2^8 = 0.256ms =256 us

方式3 8位定时器最大时间间隔 = 2^8 = 0.256ms =256 us

以上是对定时器定时的最大时间间隔做一个说明,下面具体说明怎么计算初值(小于最大时间间隔)假如定时10ms那么的定时器初值计算如下:

当使用12M晶振,12MHz除12为1MHz,也就是说一秒=1000000次机器周期。10ms=10000次 机器周期。

预置数的计算公式:

预置数=最大值-需要计数的次数
(65536-10000)

再将预置数装入16位定时计数器,如下:

TH0=(65536-10000)/256

TL0=(65536-10000)%256

当使用11.0592M晶振,11.0592MHz除12为921600Hz,就是一秒921600次机器周期,10ms=9216次机器周期。

预置数的计算公式:预置数=最大值-需要计数的次数
(65536-9216)

再将预置数装入16位定时计数器,如下:

TH0=(65536-9216)/256

TL0=(65536-9216)%256

编程

1. TMOD : 定时器工作方式

51单片机共有2个定时器:T1、T0

所以TMOD有8个bit,高四位控制 T1,、低四位控制 T0。

工作方式设置:

TMOD = 0x00(工作方式0)
TMOD = 0x01(工作方式1)
TMOD = 0x02(工作方式2)
TMOD = 0x03(工作方式3)

以上是控制低4位的,所以是对应着T0,高4位控制如下:

TMOD = 0x00(工作方式0)
TMOD = 0x10(工作方式1)
TMOD = 0x20(工作方式2)
TMOD = 0x30(工作方式3)

2. TRx:Tx使能

对于定时器T0

TR0 = 1,开始工作
TR0 = 0,停止工作

对于定时器T1

TR1 = 1,开始工作
TR1 = 0,停止工作

3. ETx:Tx中断开关

定时时间一到,就会跑去中断程序。
对于T1:

ET0 = 1,中断使能
ET0 = 0,中断失能

4. EA :中断总开关

你可以想象成电路的总电闸,EA=1,中断使能; =0,中断失能。

5. THx,TLx : Tx定时器计数寄存器

组成16位的计数:

0x0000--0xFFFF(0--65535)

只要TH0TL0=0xFFFF(65535),将会运行中断程序

在中断程序中,我们要重新给TH0,TL0重新赋值的

假设定时50毫秒,TH0,TL0的计算方法如下:

TH0,TL0,组成的16位计数器计数范围是 0-65535 。
50ms = 50 000us
只要让 TH0 TL0 从(65535 - 50000)开始计数,TH0,TL0就会不停的+1
直到TH0,TL0=65535,就是计数了50000次,时间就是过了50ms。
我们只要在中断程序里面,重新赋值给TH0,TL0=(65535 - 50000),定时器就会不停得每50ms中断一次了。

所以,TH0=(65535-50000)/256; TL0 = (65535-50000)%256 ;

程序:模式1

 // T0中断服务函数
void T0_ISR() interrupt 1
{

    TH0=(65536-16)/256;    //重新给定时器计数器赋值
    TL0=(65536-16)%256;

}

// T0中断init
void T0_init()
{
    TMOD=0x02;                    // T0模式:1
    TH0=(256-16)/256;        // 设置计时
    TL0=(256-16)%256;        
    TR0=1;                            // 使能开关
    ET0=1;                            // 中断开关
    EA=1;                                // 中断总开关
}
main()
{
    T0_init();
    while(1);
}

(TMOD = 0x01, ET0 ,TR0,TH0,TL0 ,interrput 1) 改为

(TMOD = 0x10, ET1 ,TR1,TH1,TL1 ,interrput 3) 这样就变成了T1,定时器的程序。


本文由simyng创作, 采用知识共享署名4.0 国际许可协议进行许可,转载前请务必署名
  文章最后更新时间为:December 28th , 2020 at 07:12 pm