久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9074|回復: 0
打印 上一主題 下一主題
收起左側

單片機外部中斷

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


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产精品一区二区三区 | 99精品久久久久久 | 国产一二区视频 | 亚洲香蕉在线视频 | 亚州视频在线 | 黄色日批视频 | 国产亚洲精品久久久久久牛牛 | 色视频在线免费观看 | 色婷婷av99xx| 久久久激情视频 | 色视频在线播放 | 欧美a√ | 一级黄在线观看 | 久久国内| 日韩福利电影 | 国产成人jvid在线播放 | www.婷婷 | 99re视频 | 亚洲有码转帖 | 精品一区二区三区91 | 九九久久久| 九九色综合 | 成人免费在线观看视频 | 男人天堂视频在线观看 | 日本福利在线观看 | 人妖av| 国产精品美女久久久久久免费 | 精品久久久久久久久久久久久久 | 先锋资源网站 | 欧美一级二级三级视频 | 欧美日韩在线免费观看 | 日韩一区二区三区在线 | 性色网站 | 国产乱码精品1区2区3区 | 亚洲人成在线播放 | 99久久婷婷国产精品综合 | 国产欧美日韩 | 涩爱av一区二区三区 | 成人亚洲一区 | 大陆一级毛片免费视频观看 | 伊人久久综合 |