文章目录
一、中断系统工作原理
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;
}
三、总结
在单片机应用中,常用定时器实现延时控制。通过设定定时器的计数器初值和工作模式,可以实现微秒级别的延时。在实验中,可以通过编程实现定时器的配置和中断的处理,以及相关功能的应用,加深对中断系统和定时器计数器的理解和应用。