中断和定时器

中断系统

中断介绍

中断

  中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的。
  对于单片机来讲,中断是指 CPU 在处理某一事件 A 时,发生了另一事件 B,请求 CPU 迅速去处理(中断发生);CPU 暂时停止当前的工作(中断响应), 转去 处理事件 B(中断服务);待 CPU 将事件 B 处理完毕后,再回到原来事件 A 被 中断的地方继续处理事件 A(中断返回),这一过程称为中断。
在这里插入图片描述

中断源

  引起 CPU 中断的根源称为中断源。中断源向 CPU 提出中断请求,CPU暂时中断原来的事务 A,转去处理事件 B,对事件 B 处理完毕后,再回到原来被中断 的地方(即断点),称为中断返回。实现上述中断功能的部件称为中断系统(中断机构)。

中断优先级

  微型机的中断系统一般允许多个中断源,当几个中断源同时向 CPU 请求中断,要求为它服务的时候,这就存在 CPU 优先响应哪一个中断源请求的问题。通常根据中断源的轻重缓急排队,优先 处理最紧急事件的中断请求源,即规定每一个中断源有一个优先级别。CPU 总是 先响应优先级别最高的中断请求。当两个相同优先级的中断同时产生时,将由查询次序来 决定系统先响应哪个中断。

中断嵌套

  当 CPU 正在处理一个中断源请求的时候(执行相应的中断服务程序),发生 了另外一个优先级比它还高的中断源请求。如果 CPU 能够暂停对原来中断源的 服务程序,转而去处理优先级更高的中断请求源,处理完以后,再回到原低级中 断服务程序,这样的过程称为中断嵌套。
  随着计算机技术的应用,人们发现中断技术不仅解决了快速主机与慢速 I/O 设备的数据传送问题,而且还具有如下优点:
① 分时操作。CPU 可以分时为多个 I/O 设备服务,提高了计算机的利用率;
② 实时响应。CPU 能够及时处理应用系统的随机事件,系统的实时性大大增 强;
③ 可靠性高。CPU 具有处理设备故障及掉电等突发性事件能力,从而使系统 可靠性提高。

中断资源

STC89C5X 系列单片机提供了 8 个中断请求源,它们分别是:外部中断0(INTO)、外部中断1(INT1)、外部中断2(INT2)、外部中断3(INT3)、定时器 0 中断、定时器 1 中断、定时器 2 中断、串口(UART)中断。
在这里插入图片描述

中断的结构

在这里插入图片描述

① INT0 对应的是 P3.2 口的附加功能,可由 IT0(TCON.0)选择其为低电平有 效还是下降沿有效。当 CPU 检测到 P3.2 引脚上出现有效的中断信号时,中断标 志 IE0(TCON.1)置 1,向 CPU 申请中断。
②INT1 对应的是 P3.3 口的附加功能,可由 IT1(TCON.2)选择其为低电平有 效还是下降沿有效。当 CPU 检测到 P3.3 引脚上出现有效的中断信号时,中断标 志 IE1(TCON.3)置 1,向 CPU 申请中断。
③T0 对应的是 P3.4 口的附加功能,TF0(TCON.5),片内定时/计数器 T0 溢 出中断请求标志。当定时/计数器 T0 发生溢出时,置位 TF0,并向 CPU 申请中断。
④T1 对应的是 P3.5 口的附加功能,TF1(TCON.7),片内定时/计数器 T1 溢出中断请求标志。当定时/计数器 T1 发生溢出时,置位 TF1,并向 CPU 申请中 断。⑤RXD 和 TXD 对应的是 P3.0 和 P3.1 口的附加功能,RI(SCON.0)或 TI (SCON.1),串行口中断请求标志。当串行口接收完一帧串行数据时置位 RI 或 当串行口发送完一帧串行数据时置位 TI,向 CPU 申请中断。

中断相关寄存器

CPU 对中断系统所有中断以及某个中断源的开放和屏蔽是由中断允许寄存器 IE 控制的。

中断允许控制

在这里插入图片描述

EX0(IE.0),外部中断 0 允许位;
ET0(IE.1),定时/计数器 T0 中断允许位;
EX1(IE.2),外部中断 1 允许位;
ET1(IE.3),定时/计数器 T1 中断允许位;
ES(IE.4),串行口中断允许位;
EA (IE.7), CPU 中断允许(总允许)位。

中断请求标志 TCON

在这里插入图片描述

IT0(TCON.0),外部中断 0 触发方式控制位。 当 IT0=0 时,为电平触发方式。 当 IT0=1 时,为边沿触发方式(下降沿有效)。
IE0(TCON.1),外部中断 0 中断请求标志位。
IT1(TCON.2),外部中断 1 触发方式控制位。
IE1(TCON.3),外部中断 1 中断请求标志位。
TF0(TCON.5),定时/计数器 T0 溢出中断请求标志位。
TF1(TCON.7),定时/计数器 T1 溢出中断请求标志位。

中断的优先级

外部中断0---->定时器0---->外部中断1---->定时器1---->串口

中断号

在这里插入图片描述

中断响应的三个条件

  1. 中断源有中断请求;
  2. 此中断源的中断允许位为 1;
  3. CPU 开中断(即 EA=1)。
    interrupt 是一个关键字,表示 51 单片机中断。后面的“0”是中断号,外部中断 0 中断号为 0
      下面的程序通过IE=0x85打开总中断、外部中断0和外部中断1。按键3触发外部中断0,通过按键4触发外部中断1
#include <REGX52.H>
#include "delay.h"
sbit LED1=P2^0;
sbit LED2=P2^1;
sbit LED3=P2^2;
sbit KEY3=P3^2;
void main()
{
	IE=0x85; //1000 0101
	while(1)
	{
		LED1=~LED1;
		delay_ms(500000);
	}
}

static void ex0_inter() interrupt 0//优先级为0
{
	delay_ms(500);  //消抖
	if(KEY3==0) LED2=~LED2;
}
static void ex1_inter() interrupt 2//优先级为2
{
	LED3=0;
}

定时器中断

定时器介绍

  1. 振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期)。
  2. 状态周期:2 个振荡周期为 1 个状态周期,用 S 表示。振荡周期又称 S 周期或时钟周期。
  3. 机器周期:1 个机器周期含 6 个状态周期,12 个振荡周期。
  4. 指令周期:完成 1 条指令所占用的全部时间,它以机器周期为单位。
    例如:外接晶振为 12MHz 时,51 单片机相关周期的具体值为:
    振荡周期=1/12us;
    状态周期=1/6us;
    机器周期=1us;
    指令周期=1~4us;

定时器的特点

  1. 51 单片机有两组定时器/计数器,因为既可以定时,又可以计数,故称之 为定时器/计数器。
  2. 定时器/计数器和单片机的 CPU 是相互独立的。定时器/计数器工作的过程 是自动完成的,不需要 CPU 的参与。
  3. 51 单片机中的定时器/计数器是根据机器内部的时钟或者是外部的脉冲信 号对寄存器中的数据加 1。
    有了定时器/计数器之后,可以增加单片机的效率,一些简单的重复加 1 的 工作可以交给定时器/计数器处理。CPU 转而处理一些复杂的事情。同时可以实 现精确定时作用。

定时器原理

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

定时器的结构

在这里插入图片描述

  T0 和 T1 引脚对应的是单片机 P3.4 和 P3.5 管脚。51 单片机定时/ 计数器的工作由两个特殊功能寄存器控制。TMOD 是定时/计数器的工作方式寄存 器,确定工作方式和功能;TCON 是控制寄存器,控制 T0、T1 的启动和停止及 设置溢出标志。

工作方式寄存器 TMOD

工作方式寄存器 TMOD 低四位用于 T0,高四位用于 T1。
在这里插入图片描述

在这里插入图片描述

控制寄存器 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 类同。

定时器的工作方式

方式 0

  方式 0 为 13 位计数,由 TL0 的低 5 位(高 3 位未用)和 TH0 的 8 位组成。 TL0 的低 5 位溢出时向 TH0 进位,TH0 溢出时,置位 TCON 中的 TF0 标志,向 CPU 发出中断请求。
在这里插入图片描述

方式 1

  方式 1 的计数位数是 16 位,由 TL0 作为低 8 位,TH0 作为高 8 位,组成了 16 位加 1 计数器。
在这里插入图片描述

方式 2

  方式 2 为自动重装初值的 8 位计数方式。工作方式 2 特别适合于用作较 精确的脉冲信号发生器。
在这里插入图片描述

方式 3

  方式 3 只适用于定时/计数器 T0,定时器 T1 处于方式 3 时相当于 TR1=0, 停止计数。工作方式 3 将 T0 分成为两个独立的 8 位计数器 TL0 和 TH0。
在这里插入图片描述

定时器配置

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

时间的设置

12MHZ 的外部晶振的时候,机器周期=1/1M=1us。如果我们想定时 1ms 的初值是多少呢?1ms/1us=1000。也就是要计数 1000 个,初值=65535-1000+1
main.c

#include <REGX52.H>
#include "delay.h"
#include "tube.h"

sbit LED_2=P2^5;

void Timer0_Init()
{
	//TMOD=0x01;   	// 将定时器0/计数器模式寄存器(TMOD)设置为0x01,将定时器0配置为模式1(16位定时器)
	TMOD=TMOD&(~(0x03));	//把TMOD低四位清零,高四位保持不变
	TMOD=TMOD|0x01;
	//TF0=0;     		// 清除定时器0溢出标志位(TF0)
	
	TH0=0xFC;
	TL0=0x66;
	
	ET0=1;			//打开定时器0中断允许位,允许定时器0中断
	TR0=1;    		// 设置TR0(定时器0运行)位为1,启动定时器0
	EA=1;			//打开总中断允许位,允许中断响应
	
}

void main()
{
	Timer0_Init();
	while(1);
}
void Timer0_Routine() interrupt 1
{
	static unsigned int i=0;
	static unsigned int j=0;
	static unsigned int k=0;
	static unsigned int l=0;
	//触发定时器中断
	//重装初始值
	TH0=0x4C;
	TL0=0x00;
	i++;
	
	for(j=0;j<80;j++)
	{
		if(i==59)
		{
			k+=100;
			if(k==5900)
			{
				l+=10000;
				display_10(l);
				k=0;
			}
			display_10(k);
			i=0;
		}
		
		display_10(l+k+i);
	}
}

tube.c

#include "tube.h"
unsigned char numbers[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7c,0x39,0x5E,0x79,0x71} ;
unsigned char wei[] ={0x1C,0x18,0x14,0x10,0x0C,0x08,0x04,0x00};
unsigned long mod[]={1,10,100,1000,10000,100000,1000000,10000000};

static void delay_10us(unsigned int time)
{
	while(time--);
}

// 显示十进制整数
void display_10(unsigned long num)
{
	int i=0;
	unsigned long n = 0;
	for(i=0; i<8; i++){
		P0 = 0x00;
		P2=wei[7-i];
		n = num / mod[i];
		if(n>0){
			P0 =  numbers[n%10];
		}else{
			P0 = 0x00;
		}	
		delay_10us(100);
	}	
}

tube.h

#ifndef __TUBE_H__
#define __TUBE_H__
#include <REGX52.H>
void display_10(unsigned long num);
#endif
  • 31
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值