欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

51单片机定时器

程序员文章站 2022-06-09 08:54:26
...

51单片机定时器

先上一张图 问就是很有用51单片机定时器
定时器有两个功能 定时 和 计数
定时器和计数器是单片机内部的同一个模块,通过配置 SFR(特殊功能寄存器)可以实现两种不同的功能,我们大多数情况下是使用定时器功能

1. 定时器的初步认识

在了解定时器之前我们来了解一下 时钟周期机械周期

  • 时钟周期

    时钟周期:时钟周期 T 是时序中最小的时间单位,具体计算的方法就是 1/时钟源频率 我的单片机开发板上用的晶振是 11.0592M,那么对于我这个单片机系统来说,时钟周期=1/11059200 秒。

  • 机械周期
    -我们的单片机完成一个操作的最短时间。51单片机系列,在其标准架构下一个机器周期是 12 个时钟周期,也就是 12/11059200 秒。

  • 定时器

    顾名思义,定时器就是用来进行定时的。定时器内部有一个寄存器,我们让它开始计数后,这个寄存器的值每经过一个机器周期就会自动加 1,因此,我们可以把 机器周期 理解为 定时器的 计数周期

这个定时器就是每过一个机器周期的时间,也就是 12/11059200 秒,数字自动加 1,有一个特别注意的地方,就是钟表是加到 60 后,秒就自动变成 0 了,这种情况在单片机或计算机里我们称之为溢出。那定时器加到多少才会溢出呢?后面会讲到定时器有多种工作模式,分别使用不同的位宽(指使用多少个二进制位),假如是 16 位的定时器,也就是 2 个字节,最大值就是 65535,那么加到 65535 后,再加 1 就算溢出,如果用其他位数的话,道理是一样的,对于 51 单片机来说,溢出后,这个值会直接变成 0。从某一个初始值开始,经过确定的时间后溢出,这个过程就是定时的含义。

2.定时器的寄存器
标准的 51 单片机内部有 T0 和 T1 这两个定时器,T 就是 Timer 的缩写对于单片机的每一个功能模块,都是由它的 SFR,也就是特殊功能寄存器来控制。与定时器有关的特殊功能寄存器,有以下三个

  • 定时值存储寄存器
    顾名思义 用于存储定时值 TH0/TL0 用于 T0,TH1/TL1 用于 T151单片机定时器
  • TCON定时器控制寄存器51单片机定时器大家注意在表 5-3 中的描述中,只要写到硬件置 1 或者清 0 的,就是指一旦符合条件,单片机将自动完成的动作,只要写软件置 1 或者清 0 的,是指我们必须用程序去完成这个动作
    TCON 这个 SFR,其中有 TF1、TR1、TF0、TR0 这 4 位需要我们理解清楚,它们分别对应于 T1 和 T0,我们以定时器 1 为例讲解,那么定时器 0 同理。先看 TR1,当我们程序中写 TR1 = 1 以后,定时器值就会每经过一个机器周期自动加 1,当我们程序中写 TR1 = 0以后,定时器就会停止加 1,其值会保持不变化。**TF1,这个是一个标志位,他的作用是告诉我们定时器溢出了。**比如我们的定时器设置成 16 位的模式,那么每经过一个机器周期,TL1加 1 一次,当 TL1 加到 255 后,再加 1,TL1 变成 0,TH1 会加 1 一次,如此一直加到 TH1和 TL1 都是 255(即 TH1 和 TL1 组成的 16 位整型数为 65535)以后,再加 1 一次,就会溢出了,TH1 和 TL1 同时都变为 0,只要一溢出,TF1 马上自动变成 1,告诉我们定时器溢出了,仅仅是提供给我们一个信号,让我们知道定时器溢出了,它不会对定时器是否继续运行产生任何影响。
  • TMOD定时器模式寄存器
    开头我们就提到了定时器有多种工作模式,工作模式的选择就由 TMOD 来控制51单片机定时器51单片机定时器51单片机定时器值得注意的是表 5-2 的 TCON 最后标注了**“可位寻址”,而表 5-4 的 TMOD 标注的是“不可位寻址”**。意思就是说:比如 TCON 有一个位叫 TR1,我们可以在程序中直接进行 TR1 = 1 这样的操作。但对 TMOD 里的位比如(T1)M1 = 1 这样的操作就是错误的。我们要操作就必须一次操作这整个字节,也就是必须一次性对TMOD所有位操作,不能对其中某一位单独进行操作。

表 5-6 列出的就是定时器的 4 种工作模式,其中模式 0 是为了兼容老的 8048 系列单片机而设计的,现在的 51 几乎不会用到这种模式,而模式 3 根据我的应用经验,它的功能用模式 2 完全可以取代,所以基本上也是不用的,那么**我们就重点来学习模式 1 和模式 2。**模式 1,是 THn 和 TLn 组成了一个 16 位的定时器,计数范围是 0~65535,溢出后,只要不对 THn 和 TLn 重新赋值,则从 0 开始计数。模式 2,是 8 位自动重装载模式,只有 TLn做加 1 计数,计数范围 0~255,THn 的值并不发生变化,而是保持原值,TLn 溢出后,TFn就直接置 1 了,并且 THn 原先的值直接赋给 TLn,然后 TLn 从新赋值的这个数字开始计数。这个功能可以用来产生串口的通信波特率,我们讲串口的时候要用到。

3.定时器的应用
第一步:设置特殊功能寄存器 TMOD,配置好工作模式。
第二步:设置计数寄存器 TH0 和 TL0 的初值。
第三步:设置 TCON,通过 TR0 置 1 来让定时器开始计数。
第四步:判断 TCON 寄存器的 TF0 位,监测定时器溢出情况。

写程序之前,我们要先来学会计算如何用定时器定时时间。我们的晶振是 11.0592M,时钟周期就是 1/11059200,机械周期是12/11059200,假如要定时 20ms,就是 0.02 秒,要经过x 个机器周期得到 0.02 秒,我们来算一下 x*12/11059200=0.02,得到 x= 18432。16 位定时器的溢出值是 65536(因 65535 再加 1 才是溢出),于是我们就可以这样操作,先给 TH0 和 TL0一个初始值,让它们经过 18432 个机器周期后刚好达到 65536,也就是溢出,溢出后可以通过检测 TF0 的值得知,就刚好是 0.02 秒。那么初值 y = 65536 - 18432 = 47104,转成 16 进制就是 0xB800,也就是 TH0 = 0xB8,TL0 = 0x00。

//实现小灯一秒亮一秒灭
#include <reg52.h>
sbit LED = P0^0;
void main()
{
	unsigned char cnt = 0; //定义一个计数变量,记录 T0 溢出次数
	
	TMOD = 0x01; //设置 T0 为模式 1
	TH0 = 0xB8; //为 T0 赋初值 0xB800
	TL0 = 0x00;
	TR0 = 1; //启动 T0
	while (1)
	{
		if (TF0 == 1) //判断 T0 是否溢出
		{
			TF0 = 0; //T0 溢出后,清零中断标志
			TH0 = 0xB8; //并重新赋初值
			TL0 = 0x00;
			cnt++; //计数值自加 1
			if (cnt >= 50) //判断 T0 溢出是否达到 50 次
			{
				cnt = 0; //达到 50 次后计数值清零
				LED = ~LED; //LED 取反:0-->1、1-->0
			}
		}
	}
}

最后献上我的思维导图吧51单片机定时器