中断系统工作原理及其应用


一、中断系统工作原理

1. AT89S51中断技术概述

中断技术主要用于实时监测与控制,要求单片机能及时地响应中断请求源提出的服务请求,并快速响应与及时处理。
当中断请求源发出中断请求时,如中断请求被允许,单片机暂时中止当前正在执行的主程序,转到中断服务处理程序处理中断服务请求,处理完中断服务请求后,再回到原来被中止的程序之处(断点),继续执行被中断的主程序。
中断响应和处理过程如下图所示:
在这里插入图片描述

2.AT89S51中断系统结构

在这里插入图片描述
中断系统一共有5个中断请求源:
(1)INT0*—外部中断请求0,外部中断请求信号(低电平或负跳变有效)由INT0引脚输入,中断请求标志为IE0。
(2)INT1
—外部中断请求1,外部中断请求信号(低电平或负跳变有效)由INT1*引脚输入,中断请求标志为IE1。
(3)定时器/计数器T0计数溢出的中断请求,标志为TF0。
(4)定时器/计数器T1计数溢出的中断请求,标志为TF1。
(5)串行口中断请求,标志为发送中断TI或接收中断RI。

同级中断的优先级如下表所示:
在这里插入图片描述

二、中断系统的应用

1.单一外中断

1.实验要求

在单片机P1口上接有8只LED。在外部中断0输入引脚(P3.2)接一只按钮开关K1。要求将外部中断0设置为电平触发。程序启动时,P1口上的8只LED全亮。每按一次按钮开关K1,使引脚接地,产生一个低电平触发的外中断请求,在中断服务程序中,让低4位的LED与高4位的LED交替闪烁5次。然后从中断返回,控制8只LED再次全亮。

2.Keil软件的代码实现

#include <reg51.h>
#define uchar  unsigned char
void Delay(unsigned int i)	
  {	
  	unsigned int j;
   	for(;i > 0;i--)		
   	for(j=0;j<333;j++)         
   	{
			 ;
		}			   
  }
 
void  main( )			
{	
  	EA=1;	 //总中断允许		
   	EX0=1;	 //允许外部中断0中断
   	IT0=1;	 //选择外部中断0为跳沿触发方式		
  	while(1)
		{ 
			P1=0;
		}
}		

void int0( ) interrupt 0  using 0  	//外中断0的中断服务函数
{	
  	uchar  m;
  	EX0=0;			
   	for(m=0;m<5;m++)	
  	{
			P1=0x0f;	
			Delay(400) ;		
			P1=0xf0;		
			Delay(400); 		
			EX0=1;			//中断返回前,打开外部中断0中断
    }
}

3.Proteus仿真实现

在这里插入图片描述

4.普中开发板实现

在这里插入图片描述

2、两个外中断

1.实验要求

在单片机P1口上接有8只LED。在外部中断0输入引脚(P3.2)接有一只按钮开关K1。在外部中断1输入引脚(P3.3)接有一只按钮开关K2。要求K1和K2都未按下时,P1口的8只LED呈流水灯显示,仅K1(P3.2)按下再松开时,上下各4只LED交替闪烁10次,然后再回到流水灯显示。如果按下再松开K2(P3.3)时,P1口的8只LED全部闪烁10次,然后再回到流水灯显示。设置两个外中断的优先级相同。

2.Keil软件的代码实现

#include <reg51.h>
#define uchar unsigned char
void Delay(unsigned int i)		
  {	
  	uchar j;
  	for(;i>0;i--)		
   	for(j=0;j<125;j++)		
   	{;}			
  }
	
void  main( )					
{ 
		uchar display[9]=
		{0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf, 0x7f}; 	
		unsigned int a;
		for(;;)
		{
				EA=1;		//总中断允许	 	
				EX0=1;		//允许外部中断0中断 	
				EX1=1;		//允许外部中断1中断     
				IT0=1;		//选择外部中断0为跳沿触发方式
				IT1=1;		//选择外部中断1为跳沿触发方式
				IP=0;		//两个外部中断均为低优先级
	 
				for(a=0;a<9;a++)
				{
						Delay(500);			
						P1=display[a];	
				}
  	}
}
void int0_isr(void)  interrupt 0  using 1
{	
		uchar  n;
  	for(n=0;n<10;n++)		
  	{
  	 	P1=0x0f; 		
  	 	Delay(500);		
  	 	P1=0xf0;		 
  	 	Delay(500);		
  	} 
}
	
void int1_isr (void)  interrupt 2  using 2
{	
  	uchar  m;
  	for(m=0;m<10;m++)			
   	{
  		P1=0xff;				
   		Delay(500);				
   		P1=0;					
   		Delay(500); 				
  	}
}

3.Proteus仿真实现

在这里插入图片描述

4.普中开发板实现

在这里插入图片描述

3.中断嵌套

1.实验要求

要求K1和K2都未按下时,P1口8只LED呈流水灯显示,当按一下K1时,产生一个低优先级外中断0请求(跳沿触发),进入外中断0中断服务程序,上下4只LED交替闪烁。此时按一下K2时,产生一个高优先级的外中断1请求(跳沿触发),进入外中断1中断服务程序,使8只LED全部闪烁。当显示5次后,再从外中断1返回继续执行外中断0中断服务程序,即P1口控制8只LED,上、下4只LED交替闪烁。设置外中断0为低优先级,外中断1为高优先级。

2.Keil软件的代码实现

#include <reg51.h>
#define uchar unsigned char
void Delay(unsigned int i)		
{	
		unsigned int j;
		for(;i > 0;i--)		
		for(j=0;j<125;j++)		
		{;}					
}
void  main( )		
{
  uchar display[9]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};	
	uchar a;
	for(;;)		
	{
  		EA=1;		//总中断允许
   		EX0=1;		//允许外部中断0中断
   		EX1=1;		//允许外部中断1中断	
   		IT0=1;		//选择外部中断0为跳沿触发方式
   		IT1=1;		//选择外部中断1为跳沿触发方式
   		PX0=0;		//外部中断0为低优先级
   		PX1=1;		//外部中断1为高优先级
			for(a=0;a<9;a++)		
			{						
				Delay(500);		
				P1=display[a];		
			} 	
	}
}

void int0_isr(void)  interrupt 0  using 0   
{	
  for(;;)
  {
  	P1=0x0f;		
  	Delay(400);		
  	P1=0xf0;		
		Delay(400);		
  } 							
}
void int1_isr (void)  interrupt 2  using 1  
{
		uchar m;
		for(m=0;m<5;m++)			
		{	
			P1=0;				
			Delay(500);			
			P1=0xff;			
			Delay(500);		
		}
}

3.Proteus仿真实现

在这里插入图片描述

4.普中开发板实现

在这里插入图片描述

4.定时器中断

1.实验要求

在AT89S51的P1口上接有8只LED。采用T0方式1的定时中断方式,使P1口外接的8只LED每1s闪亮一次。

2.Keil软件的代码实现

#include<reg51.h>
char  i=100;
void main ()
{
	TMOD=0x01;			
	TH0=0xee;			
	TL0=0x00;
	P1=0x00;				
	EA=1;					
	ET0=1;					
	TR0=1;					
	while(1);				
	{
		;
	}
}
void timer0() interrupt 1			
{
	TH0=0xdf;				
	TL0=0xe8;
	i--;					
	if(i<=0)
	{
		P1=~P1;			
		i=100;				
	}
}

3.Proteus仿真实现

在这里插入图片描述

4.普中开发板实现

在这里插入图片描述

5.Keil波形验证

在这里插入图片描述

6.计数器中断

1.实验要求

T1采用计数模式,方式1中断,计数输入引脚T1(P3.5)上外接按钮开关,作为计数信号输入。按4次按钮开关后,P1口的8只LED闪烁不停。

2.Keil软件的代码实现

#include <reg51.h>
void Delay(unsigned int i)		
{	
	unsigned int j;		
	for(;i>0;i--)			
	for(j=0;j<125;j++)		
	{;}				
}

void main( )				
{
	TMOD=0x50;			
	TH1=0xff;			
	TL1=0xfc;		
	EA=1;    				
	ET1=1;   			
 	TR1=1;   			
 	while(1);		  	
}

void T1_int(void)  interrupt 3  	
{
	for(;;)				
 	{	
		P1=0xff;			
 		Delay(500) ;		
 		P1=0;		
 		Delay(500); 		
	}							
}

3.Proteus仿真实现

在这里插入图片描述

4.普中开发板实现

在这里插入图片描述

5.程序改进

#include <reg51.h>

sbit LED = P2^0; 

#define MODE_OFF  0 
#define MODE_ON   1 
#define MODE_BLINK 2 /

unsigned char mode = MODE_OFF; 

void Delay(unsigned int i)		
{	
	unsigned int j;		
	for(;i>0;i--)			
		for(j=0;j<125;j++)		
		{;}				
}

void main( )				
{

	EA=1; 
	while(1) 
	{
		switch(mode) 
		{
			case MODE_OFF:
				LED = 0;
				break;
			case MODE_ON:
				LED = 1; 
				break;
			case MODE_BLINK:
				LED = ~LED; 
				break;
			default:
				break;
		}
	}
}

void key_int(void) interrupt 0
{
	if(mode == MODE_OFF)
		mode = MODE_ON; 
	else if(mode == MODE_ON)
		mode = MODE_BLINK; 
	else if(mode == MODE_BLINK)
		mode = MODE_OFF; 
}

三、总结

在单片机应用中,常用定时器实现延时控制。通过设定定时器的计数器初值和工作模式,可以实现微秒级别的延时。在实验中,可以通过编程实现定时器的配置和中断的处理,以及相关功能的应用,加深对中断系统和定时器计数器的理解和应用。

  • 18
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值