51单片机中断理解
硬件交代:P2口控制8个共阳极发光二极管,独立键盘k19控制P3^3(外部中断1);k20控制P3^2(外部中断0)。
结论1:同级(仅IP设置的同高同低)中断中,当一个中断A响应后,在执行中断服务程序期间,另一同级中断B不能嵌套打断当前中断,若B为电平触发,则B中断丢失;若为下降沿触发,则待A中断执行完,CPU会响应B
证明:
#include<reg52.h>
void delay(int z)
{
int x,y;
for(x=z;x>0;x--)
for(y=123;y>0;y--);
}
void ex1() interrupt 2
{
P2=0XAA;//如果响应则1357灯亮
delay(5000);
P2=0XFF;
}
void ex0() interrupt 0
{
P2=0X55; //如果响应则2468灯亮
}
void init()
{
EA=1;
EX0=1;
EX1=1;
IT0=1;
}
void main()
{
init();
while(1);
}
现象:程序下载后灯全灭,按下k19后松手,电平触发外部中断1 ,灯1357亮,
5秒内若不按k20,5秒内现象不变,5秒过后灯全灭
5秒内若按下k20(外部中断1响应期间向CPU申请外部中断0)后松手,现象不变,该5秒过后紧接着灯变为2468亮(CPU响应外部中断0);
说明:外部中断0没有嵌套打断当前中断,但是外部中断1执行完后外部中断0接着执行了。
若init()中把IT0=1;删除这上面两种做法后现象都是先1357亮,5秒后全灭,
说明:下降沿触发响应了,而电平触发没有响应(原因是当时电平触发时,要想中断不被丢失,必须在CPU相应之前保持低电平即IE0=1,而手松后CPU还在执行外部中断1的服务程序,等到执行完后外部中断1已经不再是低电平了所以丢失)。
所以结论被证明
结论2:高级中断可以打断低级中断(高低由IP决定),低级中断不能打断高级中断
证明:
#include<reg52.h>
#define uchar unsigned char
void delay(int z)
{
int x,y;
for(x=z;x>0;x--)
for(y=123;y>0;y--);
}
void ex1() interrupt 2
{
P2=0Xfb;
while(1);
}
void et0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=0;
delay(4000);
P2=0Xfd;
PX1=1;
while(1);
}
void init()
{
EA=1;
ET0=1;
EX1=1;
TMOD=0X01;
TR0=1;
P2=0Xfe;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
}
void main()
{
init();
while(1);
}
现象:程序下载后,先是只有第一个灯亮,4秒后,第2个灯亮,
不按k19,始终是只有第二个灯亮;按下k19后松手,只有第三个灯亮。
说明:初始化使灯一亮,4秒后,仅第2个灯亮,表明程序已经进入了定时器T0溢出中断服务程序
按下k20后松手,立马改为只有第三个灯亮,表明嵌套了,CPU停下当前正在执行定时器0中断服务程序转向外部中断1,所以高级中断可以打断低级中断。
若把et0()中PX1=0;改为PT0=1;
之前现象不变,按下k19后松手,依然只有第二个灯亮
说明:按下k19后松手,依然只有第二个灯亮,表明没有嵌套,所以低级中断不能打断高级中断
所以,结论被证明。
结论3:当同时收到多个同级的中断时,CPU将按照内部的一个优先级顺序响应中断,。该优先顺序高到低为:
外部中断0-- T0溢出中断 -- 外部中断1--- T1溢出中断--串行口中断---
n T2溢出中断(8051没有这个中断源,8052有)
n #include<reg52.h>
#define uchar unsigned char
void delay(int z)
{
int x,y;
for(x=z;x>0;x--)
for(y=123;y>0;y--);
}
void et0() interrupt 1
{
ET0=0;
P2=0XfE;
delay(4000);
}
void et1() interrupt 3
{
ET1=0;
P2=0XFD;
delay(4000);
}
void init()
{
EA=1;
TMOD=0X11;
TH0=(65535-50000)/256; TL0=(65535-50000)%256;
TH1=(65535-50000)/256; TL1=(65535-50000)%256;
ET0=1;
ET1=1;
}
void main()
{
P2=0XFF;
delay(4000);
init();
TCON=0XA0;//同时开启定时器0、1
while(1);
}
现象:程序下载后,前4秒内灯全灭; 4秒完后接着仅灯一亮,且持续4秒钟
该4秒完后变成仅灯二亮
说明:前4秒内灯全灭;是P2口初始化全灭
4秒完后接着仅灯一亮,且持续4秒,表明CPU正在执行T0的中断服务程序
该4秒完后变成仅灯二亮,表明CPU正在执行T1的中断服务程序
所以证明了在同时收到同级别(相对IP而言)的中断时,T0溢出中断比T1溢出中断要高
同样的道理,可以证明优先顺序:
外部中断0-- T0溢出中断 -- 外部中断1--- T1溢出中断--串行口中断---
n T2溢出中断(8051没有这个中断源,8052有)
所以,结论被证明。
之后我把TCON=0XA0;改为TR1=1;TR0=1;现象也是T0先响应T1后响应,
但是当我把TCON=0XA0;改为TR1=1;delay(10);TR0=1;现象则变了(T1先响应T0后响应)
现象:程序下载后,前4秒内灯全灭;
4秒完后接着仅灯二亮,且持续4秒钟 该4秒完后变成仅灯一亮
这说明:同时收到同级别(相对IP而言)的中断时,这里的同时并不是严格意义上的同时,而是当CPU还没响应前一中断,这段时间里都可以理解为同时。