微控制器中斷程式詳解(轉)
來源:http://www.51hei.com/mcu/2477.html
什麼是中斷?就是打斷當前要做的事,轉而去執行別的事情。比如小七我現在正在電腦前寫帖子,突然老媽叫我幫她下樓拿點東西,於是我就收到了老媽給我的一箇中斷(可以叫做外部中斷),當我去拿東西時,突然尿急(內部中斷,尿袋快要撐爆了),這又是一箇中斷,!我們把引起中斷的事件叫做中斷源(如老媽給我的任務,以及我的尿意。。。外部引起的叫外部中斷,內部引起的叫內部中斷),產生中斷後就要去處理它,這稱為中斷的響應。
由於尿急這個內部中斷的優先順序比老媽給我的外部中斷還要高,尿急了,我總得先去撒尿吧?所以我就先去執行撒尿這個語句(小七:怎麼我覺得這個比喻很彆扭呢
當微控制器正在執行程式的時候,突然某個按鍵按下了(產生外部中斷),微控制器就必須得去處理那個按鍵(中斷的響應),看看是發生了什麼事,按鍵處理完後繼續回來執行程式(中斷的返回)。
同樣,微控制器正在執行程式的時候,內部的定時器溢位(定時器後面會單獨講到),或者檢測到微控制器的電壓低於正常值等等(微控制器內部產生的中斷叫內部中斷),微控制器就得去處理這些事情,然後再返回來。
在微控制器裡面,中斷是有特殊的功能暫存器控制的,微控制器裡面一共有兩個中斷,一個是中斷0,一個是中斷1 ,和兩個定時器T0,T1,定時器就是你開啟它後,它會自動數數,當數到你給它限定的值時,它就會溢位,產生中斷讓CPU處理(就像一個桶,你開啟水龍頭後,水越來越多,當達到你需要的水位時,就會產生中斷叫你去處理它)。這些我們先不深入瞭解他是什麼東西,我們只需知道中斷是用下面這幾個關鍵詞控制的就行了:
IT0 宣告外部中斷0的型別,IT0=1是邊沿觸發,0是電平觸發
邊沿觸發就是當檢測到外部電平發生變化,即由低變高,或者由高變低時,就會產生一箇中斷
電平觸發就是檢測到高電平或者低電平時,產生中斷
IE0 外部邊沿觸發產生中斷後,它的值會變1,當CPU響應後,會自動變為0
IT1 和IT0一樣的含義
IE1 和IT0一樣的含義
EX0 外部中斷0控制器,EX0=1是允許外部中斷,0是禁止外部中斷,也就是不理會外部中斷
ET0 這個是定時器中斷控制器,ET1=1是允許定時器產生中斷,0是禁止
EX1,ET1的含義跟上面的都一樣。
EA 總中斷控制器,1是允許有中斷產生,0是禁止所有中斷,就算天打雷劈也不理會
另外,還有一箇中斷優先順序的控制器,就是控制是去幫媽媽拿東西的優先順序高還是去撒尿的優先順序高。
PX0 外部中斷0的優先順序控制,假如內外都產生了中斷,1就是優先處理外部中斷,0就是優先處理內部中斷
PT0 定時器0優先順序控制器,1就是優先相應定時器0
PT1 定時器1優先順序控制器,1就是優先相應定時器1
另外還有串列埠的RI,TI,PS等我們先不學習了,不然大夥該亂了
(眾人:其實我們早已凌亂了。。。一頭霧水!)
還有個概念,就是中斷請求的撤銷,也就是說,產生中斷後,會產生一箇中斷請求,為1,當CPU處理完中斷後,必須清除這個請求,不然CPU又會認為這個中斷沒有處理又跑去處理它……
對於兩個定時器產生的中斷,當CPU響應後,會自動清除TF0,TF1這兩個定製器中斷請求,處理完後就跳出來,回到原來的地方繼續執行。
對於外部中斷INT0,INT1,如果中斷型別是邊沿觸發,微控制器會自動清除中斷請求IE0,IE1
若是電平觸發,如果有一個電平,使中斷產生後,這個電平仍然還保持著,那麼這個電平還會觸發中斷,這樣CPU就死在中斷的石榴裙下出不來了。。。
(眾人:說了那麼多,沒例子你說個J8)
例子來啦!用外部中斷來控制一個LED的亮滅。對了,外部中斷並不是微控制器的每個引腳都能產生,標有INT0或INT1的才行,我們看看11F02E的引腳圖
中斷的引腳是INT0:P3^2和 INT1:P3^3,我們用邊沿觸發(由高電平變成低電平時,就會觸發)的中斷方式來控制LED,
當我們沒按下按鍵的時候,由於上拉電阻(不懂的問百度姐姐哦~)的原因,P3^2是高電平,當我們按下按鍵後,P3^2的電平就會變低,這個從高變低的過程就會產生一箇中斷(邊沿觸發),CPU會第一時間來相應這個中斷,看看是誰看帖不回貼,看完帖子不評分,然後根據小七寫的中斷處理程式去處理他!
O(∩_∩)O 。
程式怎麼寫呢?
#include <reg52.h>
sbit led=P1^7; //定義LED
void zhongduan() interrupt 0 using 1 //宣告中斷處理函式,由於是外部中斷,所以 interrupt X 裡X的值是 0
{
led=!led; //CPU響應中斷後會跑來這裡執行(讓led的狀態取反)
}
void main() //主函式,程式執行的起點
{
EA=1; //允許CPU響應所有中斷
IT0=1; //設外部中斷0的響應模式為邊沿觸發
EX0=1; //允許中斷0產生中斷
while(1); //CPU不斷在這裡死迴圈,中斷產生後放下工作去響應中斷,處理完後然後再返回來繼續死迴圈
}
按下按鍵,CPU會跑去中斷處理函式執行,執行完中斷處理後返回原處繼續執行
(眾人:這個中斷跟我們前面學習的按鍵有什麼區別麼?)
當然有區別啦!雖然都是控制LED,但是按鍵是當CPU執行到按鍵檢測如
if(key==0) 語句後,才去改變LED的狀態,如果沒有執行到,那麼即使你按下按鍵微控制器也不會響應的,也就是CPU主動去問按鍵有沒有被按下。而中斷呢,就是無論CPU在幹嘛,只要觸發中斷後,CPU就會放下手中的活,第一時間趕回來處理,也就是按鍵被按下後主動告訴CPU。。。就像windows 系統的 ctrl+alt+del 組合鍵,你一按下這個組合鍵,無論系統在做什麼,都會彈出工作管理員。
另外中斷的處理函式是這樣宣告的
void abc()
interrupt X using n
{
處理語句;
}
我們看到,只是普通的函式 加上了 interrupt X using Y 了而已,X 的取值是有規定的:
如果是外部中斷0的中斷處理函式,則X為0 即void
abc() interrupt 0 using n
若是定時器0的中斷處理函式,則
X 為1
若是外部中斷1的中斷處理函式,則
X 為2
若是定時器1的中斷處理函式,則
X 為3
若是串列埠中斷的中斷處理函式,則
X 為4
n 是中斷號,取值範圍為
0 - 31
關於中斷的學習,也到此告一段落了,當然還有一些問題沒解決.......
Q1: 為什麼count==40的時候數碼管也不能閃爍???
在除錯程式碼當中發現delay(uint z)函式與中斷是同時執行的。。。 */