今天在练习51单片机的嵌套中断时,发现了一个奇怪的点,就是中断服务函数在执行的时候,无论优先级的高低,都不能被打断。嗯,就是外部中断0和外部中断1都不能打断定时器0的中断服务函数。(优先级:外部中断0>定时器0>外部中断1).
我本来想开启定时器0,外部中断0和外部中断1,实现中断嵌套.
比如外部中断0到达时,执行中断服务函数Int0,因为它的优先级高,所以当外部中断1和定时器0到达时,不会打断外部中断0的中断服务函数。而当定时器0中断时,外部中断0到达可以打断其执行,外部中断1到达不可打断。
但是很难实现,因为开启三个中断后,每个中断的服务函数执行函数超级短,当出现现象的时候(我设置了LED灯状态翻转表示中断到达),即小灯亮起或熄灭中断函数就已经执行完了,很难控制让中断同时到达。。。
所以我这样写了代码测试:
interrupt.c
#include<reg52.h> #include<interrupt.h> //外部中断0初始化 void Int0_Init() { IT0=1; EX0=1; EA=1; } //外部中断1初始化 void Int1_Init() { IT1=1; EX1=1; EA=1; } //定时器0初始化,模式1,16位计数模式,1ms void Timer0_Init() { TMOD|=0x01; TH0=0xfc;// TL0=0x18; ET0=1; EA=1; TR0=1; } //中断服务函数 void Int0() interrupt 0 { delay(1000); if(key1==0) { led1=~led1; } } void Int1() interrupt 2 { delay(1000); if(key2==0) { led1=~led1; } } void Timer0() interrupt 1 { TH0=0xfc; TL0=0x18; i++; if(i==10000) { led1=~led1; i=0; while(1); } } //延时函数,为了消抖 void delay(u16 j) { while(j--); }
interrupt.h
#include<reg52.h> typedef unsigned char u8; typedef unsigned int u16; //初始化函数 void Int0_Init(); void Int1_Init(); void Timer0_Init(); void Timer1_Init(); //中断服务函数 void Int0(); void Int1(); void Timer0(); void Timer1(); void delay(u16 j); static u16 i=0; sbit key1=P3^2; sbit key2=P3^3; sbit led1=P0^0;
main.c
#include<reg52.h> #include<interrupt.h> int main() { Int0_Init(); Int1_Init(); led1=0; Timer0_Init(); // Timer1_Init(); while(1) ; }
嗯,这样写完后,我以为能实现我想要的结果,但是现象 是这样的:
我在定时器0的中断服务函数中加入的while(1)循环,Timer0函数就不会退出。但是实验结果是Timer0不能被打断,即当定时器0的中断未到达时,外部中断0和外部在中断1都能控制LED1的亮灭,当定时器1中断达到时,在中断服务函数Timer0执行时 ,外部中断0和外部中断1的到达不能中断定时器0的服务函数。
那么问题来了,51单片机怎能实现中断嵌套呢?或者说是怎样控制外部中断和定时器中断的同时到达以便确认中断的优先级排序?困扰的很啊。。。