<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 單片機外部中斷詳解及程序

單片機外部中斷詳解及程序

作者: 時(shí)間:2016-12-01 來(lái)源:網(wǎng)絡(luò ) 收藏
單片機在自主運行的時(shí)候一般是在執行一個(gè)死循環(huán)程序,在沒(méi)有外界干擾(輸入信號)的時(shí)候它基本處于一個(gè)封閉狀態(tài)。比如一個(gè)電子時(shí)鐘,它會(huì )按時(shí)、分、秒的規律來(lái)自主運行并通過(guò)輸出設備(如液晶顯示屏)把時(shí)間顯示出來(lái)。在不需要對它進(jìn)行調校的時(shí)候它不需要外部干預,自主封閉地運行。如果這個(gè)時(shí)鐘足夠準確而又不掉電的話(huà),它可能一直處于這種封閉運行狀態(tài)。但事情往往不會(huì )如此簡(jiǎn)單,在時(shí)鐘剛剛上電、或時(shí)鐘需要重新校準、甚至時(shí)鐘被帶到了不同的時(shí)區的時(shí)候,就需要重新調校時(shí)鐘,這時(shí)就要求時(shí)鐘就必須具有調校功能。因此單片機系統往往又不會(huì )是一個(gè)單純的封閉系統,它有些時(shí)候恰恰需要外部的干預,這也就是外部中斷產(chǎn)生的根本原由。
實(shí)際上在第二個(gè)示例演示中,就已經(jīng)舉過(guò)有按鍵輸入的例子了,只不過(guò)當時(shí)使用的方法并不是外部中斷,而是用程序查詢(xún)的方式。下面就用外部中斷的方法來(lái)改寫(xiě)一下第二個(gè)示例中,通過(guò)按鍵來(lái)更改閃爍速度的例子(第二個(gè)例子)。電路結構和接線(xiàn)不變,僅把程序改為下面的形式。
#include
unsigned int t=500; //定義一個(gè)全局變量t,并設定初始值為500次
//===========延時(shí)子函數,在8MHz晶振時(shí)約1ms=============
void delay_ms(unsigned int k)
{
unsigned int i,j;
for(i=0;i{
for(j=0;j<1140;j++)
;
}
}
//============主函數==================================
void main( void )
{
DDRB = 0xFF; //設置端口B為輸出方向
PORTB = 0xFF; //設置端口B的輸出為全高電平
DDRD = 0x00; //設置端口D為輸入方向
PORTD = 0xFF; //設定端口D為內部上拉方式,無(wú)信號輸入時(shí)處于高電平狀態(tài)
MCUCR = 0x0A; //設定INT0、INT1為下降沿觸發(fā)
GICR = 0xC0; //使能INT0、INT1中斷
SREG = 0x80; //使能總中斷
while(1)
{
PORTB = 0x55; //讓接在端口B上的LED顯示01010101
delay_ms(t); //延時(shí)t個(gè)ms
PORTB = 0xAA; //讓接在端口B上的LED顯示01010101
delay_ms(t); //延時(shí)t個(gè)ms
}
}
//============中斷函數(外部0)==========================
#pragma vector = INT0_vect
__interrupt void INT0_Server(void)
{
t = 100; //設定t的值為100次
}
//============中斷函數(外部1)==========================
#pragmavector= INT1_vect
__interrupt void INT1_Server(void)
{
t = 500; //設定t的值為500次
}
把上述程序進(jìn)行編譯并下載到單片機中,可以看到結果與第二個(gè)示例中的完全一致。下面就來(lái)分析一下鍵盤(pán)中斷的程序原理。
在分析程序之前,先來(lái)了解一下什么叫“外部中斷”。前面已講述過(guò),在沒(méi)有打擾的情況下,單片機的程序在封閉狀態(tài)下自主運行,但如果在某一時(shí)刻需要響應一個(gè)外部事件(比如有按鍵被按下),這時(shí)就需要用外部中斷。具體來(lái)講,外部中斷就是在單片機的一個(gè)引腳上,由于外部因素導致了一個(gè)電平的變化(比如由高變低),而通過(guò)捕獲到這個(gè)變化,單片機內部自主執行的程序就被暫時(shí)打斷,轉而去執行相應的中斷處理程序,執行完后又回到原來(lái)中斷的地方繼續執行原程序。這個(gè)引腳上的電平變化,就申請了一個(gè)外部中斷事件,而這個(gè)能申請外部中斷的引腳就是外部中斷的觸發(fā)引腳。在上面的例子中,可以看到兩個(gè)按鍵S1、S2被接到了ATMega16的PD3和PD2引腳,而這兩個(gè)引腳正是該單片機的兩個(gè)外部中斷(INT1和INT0)的觸發(fā)引腳(第二功能)。當按鍵沒(méi)有按下時(shí),這兩個(gè)引腳都為高電平(執行過(guò)PORTD=0xFF),當按鍵被按下時(shí),引腳電平跳變?yōu)榈碗娖?,這時(shí)若單片機設置成允許中斷申請,就會(huì )觸發(fā)外部中斷事件,從而轉去執行中斷服務(wù)程序。明白了這個(gè)過(guò)程之后,接下來(lái)就可以分析程序了。
程序執行后,主程序就一直在不停的運行while(1)內的這個(gè)死循環(huán),讓LED以t=500ms的初始值來(lái)交替閃爍,直到有外部中斷來(lái)打斷它。假設某一時(shí)刻按鍵S2被按下,這時(shí)由于引腳PD2上的電平突然被拉低,申請了一個(gè)外部中斷0(INT0),這時(shí)的程序就轉去執行外部中斷0的中斷服務(wù)程序(即__interrupt void INT0_Server(void)函數)。這時(shí)全局變量t的值被該函數重新賦值為100(即延時(shí)為100ms),完成后又回到主函數中的while(1)內去繼續執行,因此LED閃爍的速度就變快了。
觀(guān)察程序可看出,如果沒(méi)有中斷去調用中斷服務(wù)子程序,在主程序中是沒(méi)有語(yǔ)句去調動(dòng)它的。也就是說(shuō)如果沒(méi)有外部中斷,中斷服務(wù)子程序(即__interrupt void INT0_Server(void)函數)是永遠不會(huì )被執行的。這也說(shuō)明,中斷服務(wù)子程序是一類(lèi)特殊的子程序,它不能被主程序調用,只能被中斷申請調用。因此,中斷服務(wù)子程序有它固定的格式和寫(xiě)法。在不同的編譯系統中的寫(xiě)法不完全一樣,下面給出IAR下的中斷服務(wù)子程序的格式。
#pragmavector= INT0_vect
__interrupt void INT0_Server(void)
{
中斷服務(wù)程序代碼
}
以上是固定格式,除斜體部分外,其余部分不可更改。斜體部分中的INT0_vect表示中斷的向量號,不同的中斷名稱(chēng)不一樣(原型在頭文件iom16.h中)。斜體部分中的INT0_Server是中斷函數的名稱(chēng),是由開(kāi)發(fā)者自己定義的。雖然可以自定義,但名稱(chēng)還是要取得“見(jiàn)名知義”,這樣一看就知道是什么中斷服務(wù)了。


評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>