51单片机 | 定时器中断实验

本文详细介绍了51单片机的定时器原理、结构和工作方式,重点讲述了定时器配置,包括工作模式设置、初值计算,并提供了硬件设计和软件设计的实例,以定时器中断控制LED闪烁为例,帮助理解定时器在实际应用中的操作流程。
AI助手已提取文章相关产品:


  这一节介绍51单片机的定时器中断。 STC89C5X 含有 3 个定时器:定时器 0、定时器 1、定时器 2(注意: 51 系列单片机一定有基本的 2 个定时器(定时器 0 和定时器 1),但不全有 3 个中断,需要查看芯片手册,通常我们使用的是基本的 2 个定时器:定时器 0/1)。本节要实现的功能是通过定时器 0 中断控制 D1 指示灯间隔 1 秒闪烁。

一、定时器介绍

  在介绍定时器之前需要先科普下几个知识:

  1. CPU 时序的有关知识

    • 振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期)。
    • 状态周期:2 个振荡周期为 1 个状态周期,用 S 表示。振荡周期又称 S 周期或时钟周期。
    • 机器周期:1 个机器周期含 6 个状态周期,12 个振荡周期。
    • 指令周期::完成 1 条指令所占用的全部时间,它以机器周期为单位。

    例如:外接晶振为 12MHz 时,51 单片机相关周期的具体值为:
    振荡周期=1/12us;
    状态周期=1/6us;
    机器周期=1us;
    指令周期=1~4us;

  2. 学习定时器前需要明白几点

    • 51 单片机有两组定时器/计数器,因为既可以定时,又可以计数,故称之为定时器/计数器。
    • 定时器/计数器和单片机的 CPU相互独立的。定时器/计数器工作的过程是自动完成的,不需要 CPU 的参与。
    • 51 单片机中的定时器/计数器是根据机器内部的时钟或者是外部的脉冲信号对寄存器中的数据加 1。

    有了定时器/计数器之后,可以增加单片机的效率,一些简单的重复加 1 的工作可以交给定时器/计数器处理。CPU 转而处理一些复杂的事情。同时可以实现精确定时作用。

1. 51 单片机定时器原理

  STC89C5X 单片机内有两个可编程的定时/计数器 T0T1 和一个特殊功能定时器 T2。定时/计数器的实质是加 1 计数器(16 位),由高 8 位和低 8 位两个寄存器 THxTLx 组成。它随着计数器的输入脉冲进行自加 1,也就是每来一个脉冲,计数器就自动加 1,当加到计数器为全 1 时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置 1,向 CPU 发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。可见,由溢出时计数器的值减去计数初值才是加 1 计数器的计数值。

2. 51 单片机定时/计数器结构

  51 单片机定时器/计数器内部结构如下所示:
在这里插入图片描述
上图中的 T0T1 引脚对应的是单片机 P3.4P3.5 管脚的附加功能。51 单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD 是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON控制寄存器,控制 T0T1 的启动和停止及设置溢出标志。

  1. 工作方式寄存器 TMOD
    工作方式寄存器 TMOD 用于设置定时/计数器的工作方式,低四位用于 T0,高四位用于 T1。其格式如下:
    在这里插入图片描述
    GATE 是门控位,GATE=0 时,用于控制定时器的启动是否受外部中断源信号的影响。只要用软件使 TCON 中的 TR0TR11,就可以启动定时/计数器工作;GATA=1 时,要用软件使 TR0TR11,同时外部中断引脚 INT0/1 也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了 INT0/1 引脚为高电平这一条件。
    • C/T :定时/计数模式选择位。C/T =0 为定时模式;C/T =1 为计数模式。
    • M1M0:工作方式设置位。定时/计数器有四种工作方式。
      在这里插入图片描述
  2. 控制寄存器 TCON
    TCON 的低 4 位用于控制外部中断,已在前面介绍。TCON 的高 4 位用于控制定时/计数器的启动和中断申请。其格式如下:
    在这里插入图片描述
    • TF1(TCON.7)T1 溢出中断请求标志位。T1 计数溢出时由硬件自动置 TF1为 1。CPU 响应中断后 TF1 由硬件自动清 0。T1 工作时,CPU 可随时查询 TF1 的状态。所以,TF1 可用作查询测试的标志。TF1 也可以用软件置 1 或清 0,同硬件置 1 或清 0 的效果一样。
    • TR1(TCON.6)T1 运行控制位。TR1 置 1 时,T1 开始工作;TR1 置 0 时,T1 停止工作。TR1 由软件置 1 或清 0。所以,用软件可控制定时/计数器的启动与停止。
    • TF0(TCON.5)T0 溢出中断请求标志位,其功能与 TF1 类同。
    • TR0(TCON.4)T0 运行控制位,其功能与 TR1 类同。

3. 51 单片机定时/计数器的工作方式

  1. 方式0
    方式 0 为 13 位计数,由 TL0 的低 5 位(高 3 位未用)和 TH0 的 8 位组成。TL0 的低 5 位溢出时向 TH0 进位,TH0 溢出时,置位 TCON 中的 TF0 标志,向 CPU发出中断请求。其结构图如下所示:
    在这里插入图片描述
    门控位 GATE 具有特殊的作用。当 GATE=0 时,经反相后使或门输出为 1,此时仅由 TR0 控制与门的开启,与门输出 1 时,控制开关接通,计数开始;当 GATE=1时,由外中断引脚信号控制或门的输出,此时控制与门的开启由外中断引脚信号和 TR0 共同控制。当 TR0=1 时,外中断引脚信号引脚的高电平启动计数,外中断引脚信号引脚的低电平停止计数。这种方式常用来测量外中断引脚上正脉冲的宽度。计数模式时,计数脉冲是 T0 引脚上的外部脉冲。计数初值与计数个数的关系为: X = 2 13 − N X=2 ^{13}-N X=213N

  2. 方式1
    方式 1 的计数位数是 16 位,由 TL0 作为低 8 位,TH0 作为高 8 位,组成了16 位加 1 计数器。其结构图如下所示:
    在这里插入图片描述
    计数初值与计数个数的关系为: X = 2 16 − N X=2^{16}-N X=216N

  3. 方式2
    方式 2 为自动重装初值的 8 位计数方式。工作方式 2 特别适合于用作较精确的脉冲信号发生器。其结构图如下所示:
    在这里插入图片描述
    计数初值与计数个数的关系为: X = 2 8 − N X=2^8-N X=28N

  4. 方式3
    方式 3 只适用于定时/计数器 T0,定时器 T1 处于方式 3 时相当于 TR1=0,停止计数。工作方式 3 将T0 分成为两个独立的 8 位计数器 TL0TH0。其结构如下所示:
    在这里插入图片描述
    这几种工作方式中应用较多的是方式 1 和方式 2。定时器中通常使用定时器方式 1,串口通信中通常使用方式 2。

二、定时器配置

  在使用定时器时,应该如何配置使其工作?其步骤如下(各步骤顺序可任意):

  1. TMOD 赋值,以确定 T0T1 的工作方式,如果使用定时器 0 即对 T0 配置,如果使用定时器 1 即对 T1 配置。
  2. 根据所要定时的时间计算初值,并将其写入 TH0TL0TH1TL1
  3. 如果使用中断,则对 EA 赋值,开放定时器中断。
  4. 使 TR0TR1 置位,启动定时/计数器定时或计数。

上述中有一个定时/计数器初值的计算,下面我们来看下如何计算定时/计数器初值。
  前面我们介绍过机器周期的概念,它是 CPU 完成一个基本操作所需要的时间。其计算公式是:机器周期=1/单片机的时钟频率。51 单片机内部时钟频率是外部时钟的 12 分频,也就是说当外部晶振的频率输入到单片机里面的时候要进行 12分频。比如说你用的是 12MHZ 晶振,那么单片机内部的时钟频率就是 12/12MHZ,当你使用 12MHZ 的外部晶振的时候,机器周期=1/1M=1us。如果我们想定时 1ms的初值是多少呢?1ms/1us=1000。也就是要计数 1000 个,初值=65535-1000+1(因为实际上计数器计数到 65536(2 的 16 次方)才溢出,所以后面要加 1)=64536=FC18H,所以初值即为 THx=0XFCTLx=0X18
  知道了如何计算定时/计数器初值,那么想定时多长时间都可以计算出,当然由于定时计数器位数有限,我们不可能直接通过初值定时很长时间,如果要实现很长时间的定时,比如定时 1 秒钟。可以通过初值设置定时 1ms,每当定时 1ms结束后又重新赋初值,并且设定一个全局变量累计定时 1ms 的次数,当累计到1000 次,表示已经定时 1 秒了。需要其他定时时间类似操作,这样我们就可以使用定时器来实现精确延时来替代之前的 delay 函数。
  这里以定时器 0 为例介绍配置定时器工作方式 1、设定 1ms 初值,开启定时器计数功能以及总中断,如下:

void time0_init(void)
{
	TMOD|=0X01;//选择为定时器 0 模式,工作方式 1
	TH0=0XFC; //给定时器赋初值,定时 1ms
	TL0=0X18;
	ET0=1;//打开定时器 0 中断允许
	EA=1;//打开总中断
	TR0=1;//打开定时器
}

对于定时器 1 的使用方法是一样的,只是将上述的 0 变为 1 即可,具体可参考我们定时器 1 实验例程。

void time1_init(void)
{
	TMOD|=0X10;//选择为定时器 1 模式,工作方式 1
	TH1=0XFC; //给定时器赋初值,定时 1ms
	TL1=0X18;
	ET1=1;//打开定时器 1 中断允许
	EA=1;//打开总中断
	TR1=1;//打开定时器
}

三、硬件设计

  本实验使用到硬件资源如下:

  • LED 模块(D1)
  • 定时器 0

本节硬件电路非常简单,只使用到开发板上 LED 模块的 D1,至于定时器 0它属于 51 单片机内部资源,只需通过软件配置即可使用。开发板上 LED 模块电路在前面已经介绍,这里就不多说。

四、软件设计

  本节所要实现的功能是:通过定时器 0 中断控制 D1 指示灯间隔 1 秒闪烁。
  我们直接复制前面创建好的工程模板,将复制过来的模板文件夹重新命名为“17-定时器实验”。打开工程直接在 main.c 源文件内进行编程,main.c 内代码如下:

/*
实验名称:定时器 0 实验
接线说明:
实验现象:下载程序后,当按下 D1 指示灯间隔 1s 闪烁
注意事项:
*/

#include "reg52.h"

//对系统默认数据类型进行重定义 
typedef unsigned char u8;
typedef unsigned int u16;

//定义LED1管脚
sbit LED1 = P2^0;


/*
函 数 名 : time0_init
函数功能 : 定时器 0 中断配置函数,通过设置 TH 和 TL 即可确定定时时间
输 入 : 无
输 出 : 无
补充:选择定时器工作模式 0、工作方式 1、设置定时 1ms 初值、打开定时器计数功能和开启总中断功能
*/
void time0_init(void)
{
	TMOD|=0X01;//选择为定时器 0 模式,工作方式 1
	TH0=0XFC; //给定时器赋初值,定时 1ms
	TL0=0X18;
	ET0=1;//打开定时器 0 中断允许
	EA=1;//打开总中断
	TR0=1;//打开定时器	
}


/*
函 数 名 : main
函数功能 : 主函数
输 入 : 无
输 出 : 无
详细说明 : 
*/
void main()
{	
	time0_init(); //定时器0初始化配置

	//这里主程序并未配置
	while (1)
	{  	

	}
}

/*
函 数 名 : time0
函数功能 : 定时器0中断服务函数
输 入 : 无
输 出 : 无
*/
void time0() interrupt 1 //定时器0中断函数
{
	//定义静态变量i
	static u16 i;
	//给定时器赋初值,定时1ms
	TH0 = 0XFC;
	TL0 = 0X18;

	i++;
	if (i == 1000)
	{
		i = 0;  //清零变量
		LED1 = !LED1;  //状态翻转
	}
}

至此,整个程序就编写完成,我们编译一下,如下图所示:
在这里插入图片描述
可以看到没有错误,也没有警告。
  首先,定义 LED1 指示灯控制管脚,然后定义定时器 0 中断配置函数 time0_init,该函数配置内容选择定时器工作模式 0、工作方式 1、设置定时 1ms 初值、打开定时器计数功能和开启总中断功能。然后进入while 循环,在循环体内没有执行任何功能程序。当定时时间到达即会进入定时器 0 中断,在中断服务函数内,重新赋初值准备下次计数,并且定义一个静态变量来累计定时 1ms 次数,当变量等于 1000 时,表示定时时间达 1 秒,然后清零变量以及控制 LED 状态翻转。执行完成后退出中断返回主函数,当时间到达又进入中断,如此循环。

五、实验现象

  使用 USB 线将开发板和电脑连接成功后(电脑能识别开发板上 CH340 串口),把编译后产生的.hex 文件烧入到芯片内,实现现象如下:当 D1 指示灯间隔 1s闪烁。
注意:实验中我们是以 12M 晶振为例讲解初值的计算,假如外部晶振为11.0592M,那么使用前面的计算公式可能就比较繁琐,这里给大家推荐一个非常好用的小工具“定时器计算.exe”,打开小工具,选择好定时器工作方式、晶振频率、定时时长即可得出 THTL 的初值。假如现在使用的晶振是 11.0592M,使用定时器方式 1,定时时间为 1ms,设置界面如下:
在这里插入图片描述
  定时器初值为 TH0=0XFCTL0=0X66。该值与前面 12M 晶振得到的初值是有差别的,这也就是很多同学咨询为什么开发板上定时器工作慢或者快的原因,一定要注意开发板上使用的外部晶振大小,晶振大小不同,换算的初值是不一样的。

您可能感兴趣的与本文相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值