中断相关的基础概念
内核和外设之间的主要交互方式有两种:轮询和中断。
在执行cpu当前程序时,由于系统中出现了某种急需处理的情况,cpu暂停正在执行的程序,转而去执行另外一段特殊的程序来处理出现的紧急事务,处理结束后,CPU自动返回到原来暂停的程序中去继续执行。这种程序在执行过程中由于外界的原因而被中间打断的情况,成为中断。
中断服务函数:内核响应中断后执行的相应处理程序。
中短向量:中断服务函数的入口地址。每个中断源都对应一个固定的入口地址。当内核响应中断请求时,就会暂停当前的程序执行,然后跳转到该入口地址执行代码。
有中断请求不一定能打断主程序。
首先将J5处的跳帽接到2 ~ 3 引脚,即S5按键接到P32/INT0,S4按键接到P33/INT1。定义一个working函数,使L1指示灯不断闪烁。将P32引脚定义为外部中断功能,按键S5按键就会产生外部中断触发信号,在中断响应函数中,点亮L8指示灯,延长一段时间后熄灭,该功能用两种方式实现:
1-直接在中断服务函数中延时
2-在中断服务函数中标志变量,在外部执行延时
#include "reg52.h"
sbit L1 = P0^0;
sbit L8 = P0^7;
void Delay(unsigned int t)
{
while(t--);
}
void SelectHC573()
{
P2 = (P2 & 0x1f )| 0x80;
}
void Working()
{
SelectHC573();
L1=0;
Delay(60000);
L1=1;
Delay(60000);
}
//===========================
void Init_INT0()
{
IT0 = 1; //下降沿触发
EX0=1;//外部中断使能打开
EA=1;//总中断打开
}
void ServiceINT0() interrupt 0 //外部中断0的中断号是0
{
L8=0;
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
L8=1;
}
//===========================
void main()
{
while(1)
{
Init_INT0();
Working();
}
}
上面的这个代码将延时函数放在了中断服务函数中。
这个的结果是当使L1闪烁时,按下S5,L8亮,但L1可以亮,可以不亮。这取决于按下的时间点。
如果将延时放在中断服务函数外面 即:
#include "reg52.h"
sbit L1 = P0^0;
sbit L8 = P0^7;
void Delay(unsigned int t)
{
while(t--);
}
void SelectHC573()
{
P2 = (P2 & 0x1f )| 0x80;
}
void Working()
{
SelectHC573();
L1=0;
Delay(60000);
L1=1;
Delay(60000);
}
//===========================
void Init_INT0()
{
IT0 = 1; //下降沿触发
EX0=1;//外部中断使能打开
EA=1;//总中断打开
}
unsigned char stat_int=0;
void ServiceINT0() interrupt 0 //外部中断0的中断号是0
{
stat_int=1;
}
void LEDINT()
{
if(stat_int==1)
{
L8=0;
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
L8=1;
}
stat_int=0;
}
//===========================
void main()
{
Init_INT0();
while(1)
{
Working();
LEDINT();
}
}
上面这个代码将延时放在了另一个函数中,而中断服务函数中只有标志变量的改变。
这就使得当有一个中断进来使标志变量改变时,必须等到working执行完之后(即L1闪烁一次之后),才会检测变量的值,在决定L8是否点亮。
注意
一般在中断服务函数中不要写太多的语句。