今天在練習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單片機怎能實現中斷嵌套呢?或者說是怎樣控制外部中斷和定時器中斷的同時到達以便確認中斷的優先級排序?困擾的很啊。。。