中斷,顧名思義就是停止現在正在做的事情,去做其他的事情。就像你在上班,這時來了個電話,你就要停下手中的活,去接電話。而要我們暫時停下手中的活的電話就叫做中斷源。可以說是中斷讓單片機的工作變得豐富且更有條理,就像生活中這個電話可能是約會奧。
一、簡介
51的中斷系統如下圖所示:
從圖中可以看出:51有5個中斷源,INT0(外部中斷0),IF0(定時器0),INT(外部中斷1),IF1(定時器1),TI/RI(串行中斷)。
每個中斷源都有一個控制開關。開關打開,即使中斷來了也不去響應,就像我們可以不去理開始說的那個電話。所有的中斷源又由一個總開關統一控制,就像公司有很多部電話,但是交換機電源關掉了,所有的電話就都不會響了。
所有的中斷源又按重要程度分了優先級(執行的先后順序),還是討厭的電話,兩部擺在面前,一個是客戶的,一個是哥們的。當然了,先接客戶的。
另外中斷又可以分為可屏蔽中斷和不可屏蔽中斷,很容易理解,就像51的所有中斷,都帶有控制是否接通的開關,這就是可以屏蔽的,叫做可屏蔽中斷。當然還有開關沒有辦法控制的中斷源,這個叫做不可屏蔽中斷。
二、中斷的作用或者特征
中斷到底能有什么作用呢?眾所周之,我們只有一個腦袋,兩只手,不會分身術,所以同一個時刻只能做一件事情,當然孫悟空和哪吒除外。單片機的CPU也一樣,程序在正常情況下只能順序執行,但是有些事情你不會預知它什么時候會發生,比如我按了下按鍵,單片機當然可以一直都在查看你是否按下了按鍵,然后做相應的處理,但是如果CPU一直都在查看按鍵的狀態,但是你半天都不按一個按鍵,那好了,它大部分的時間都在做無用功,這樣做事可以,但是效率很低,還有一個很難處理的問題就是,如果我們的程序很龐大(或者中間有較長時間的延時),那么程序每循環一圈的時間就會很長,有個情況就是你按下了按鍵,但是CPU那時沒有在查詢按鍵狀態,那么這就沒辦法相應了。就像我們不可能派個人去客戶那里一直呆着,有問題了,他就回來報告下,然后在去那里“蹲點”。
有個中斷就不一樣了,安個電話嘛!有事call me。萬事OK。更近一點說,一個公司會有很多客戶,不同方面的(供應商,代理商,直接客戶==),相應的就會有不同的電話(技術支持,代理咨詢==)。而這些不同的客戶的電話的接聽也是可以有先后順序的,供應商的電話當然可以放在代理商的后面,畢竟他們是賣產品給我們的,我們賺錢還是靠賣產品滴。這就道出了一個優先級處理的問題。
中斷還有一個很重要的特征就是嵌套,這個需要單獨說明。
由此可以得出一個結論:中斷的存在解決了一個資源共享的問題,就是很多的事件不論什么時候發生,都可以得到響應。很多事情同時發生的時候,可以按照重要性分別對待。
三、中斷到底做了什么?
還是那個電話的例子,如果你正在整理資料,電話響了,你會在正整理的資料上做個記號,然后去接電話,電話接完了,你會找到之前做到記號,然后再接着整理。CPU執行中斷操作的過程就像這個一樣:
單片機CPU檢測中斷發生的時候,會保存斷點(此時CPU執行的所有的寄存器的值)也叫現場保護,然后在跳轉到中斷服務程序,執行完了之后。會取出保存的斷點,繼續執行原來的程序。如果在書寫匯編程序的時候,需要手動編寫斷點保存和恢復的程序,(push和pop指令);而如果使用C編寫程序,則需要在中斷服務程序上加特殊的關鍵字,編譯器在編譯的時候就會自動的做斷點保存和恢復的操作。(比如keil里使用interrupt 關鍵字)。
MCS-51CPU在每一個機器周期順序檢查每一個中斷源,在機器周期的S6按優先級處理所有被激活的中斷請求,此時,如果CPU沒有正在處理更高或相同優先級的中斷,或者現在的機器周期不是所執行指令的最后一個機器周期,或者CPU不是正在執行RETI指令或訪問IE和IP的指令(因為按MCS-51中斷系統的特性規定,在執行完這些指令之后,還要在繼續執行一條指令,才會響應中斷),CPU在下一個機器周期響應激活了的最高級中斷請求。
中斷響應的主要內容就是由硬件自動生成一條長調用LCALL addr16指令,這里的addr16就是程序存儲器中相應的中斷區入口地址,這些中斷源的服務程序入口地址如下:
表5 個中斷源的服務程序入口地址 | |||||||||
中斷源 | 入口地址 | ||||||||
外中斷0 | 0003H | ||||||||
定時/計數器0 | 000BH | ||||||||
外中斷1 | 0013H | ||||||||
定時/計數器0 | 001BH | ||||||||
串行口中斷 | 0023H |
生成LCALL指令后,CPU緊跟着便執行之.首先將PC(程序計數器)的內容壓入堆棧保護斷點,然后把中斷入口地址賦予PC,CPU便按新的PC地址(即中斷服務程序入口地址)執行程序。 值得一提的是,各中斷區只有8個單元,一般情況下(除非中斷程序非常簡單),都不可能安裝下一個完整的中斷服務程序。因此,通常是在這些入口地址區放置一條無條件轉移指令,使程序按轉移的實際地址去執行真正的中斷服務程序。 |
四、中斷嵌套
51有兩級中斷,就是說中斷是有優先級,如果兩個中斷同時到達,那么一定要先響應優先級比較高的那個中斷,你再郁悶也不行。當然更郁悶的是如果中斷在執行過程中,如果有高優先級的中斷來了,也要去響應高優先級的中斷。這就是中斷的嵌套
中斷嵌套和中斷優先級有關,簡單的說就是中斷服務程序執行的時候又來了中斷,它中斷了之前正在執行的中斷。很拗口的話,畫個圖說明下吧:
五、中斷有關寄存器:
1.TCON
TCON 寄存器的每一位都控制一個中斷源,它們的對應關系如下:
TF0 ,TF1:定時器中斷的控制位。
IE1:外部邊沿觸發中斷1請求標志,其功能和操作類似於TF0。
IT1:外部中斷1類型控制位,通過軟件設置或清楚,用於控制外中斷的觸發信號類型。IT1=1,邊沿觸發。IT=0是電平觸發。
IT1:外部中斷1類型控制位,通過軟件設置或清楚,用於控制外中斷的觸發信號類型。IT1=1,邊沿觸發。IT=0是電平觸發。
IT1:外部中斷1類型控制位,通過軟件設置或清楚,用於控制外中斷的觸發信號類型。IT1=1,邊沿觸發。IT=0是電平觸發。
2.SCON
SCON是串行口中斷控制器,只有低2位是有意義的,其他位保留:
TI:MCS-51串行口的發送中斷標志,在串行口以方式0發送時,每當發送完8位數據,由硬件置位。如果以方式1、方式2或方式3發送時,在發送停止位的開始時TI被置1,TI=1表示串行發送器正向CPU發出中斷請求,向串行口的數據緩沖器SBUF寫入一個數據后就立即啟動發送器繼續發送。但是CPU響應中斷請求后,轉向執行中斷服務程序時,並不清零TI,TI必須由用戶的中斷服務程序清“0”,即中斷服務程序必須有TI=0;(“CLR TI”或“ANL SCON, #0FDH”等指令)來清零TI。
RI:串行口接收中斷標志.若串行口接收器允許接收,並以方式0工作,每當接收到8位數據時,RI被置1,若以方式1、2、3方式工作,當接收到半個停止位時,TI被置1,當串行口一方式2或3方式工作,且當SM2=1時,僅當接收到第9位數據RB8為1后,同時還要在接收到半個停止位時,RI被置1。RI為1表示串行口接收器正向CPU申請中斷。同樣RI標志必須由用戶的軟件清“0”。
3.IE
IE叫做中斷控制寄存器,51所有中斷的開啟屏蔽都是由它來控制,它的各位的情況如下:
EA:中斷總控制位,也就是中斷的總開關,在第一個圖中可以很明確的看到。EA=1,CPU開放中斷。EA=0,CPU禁止所有中斷。
ES:串行口中斷控制位,ES=1允許串行口中斷,ES=0,屏蔽串行口中斷。
ETx:定時/計數器Tx中斷控制位。ETx=1,允許Tx中斷,ETx=0,禁止Tx中斷。(其中x=0.1)
EXx:外中斷1中斷控制位,EXx=1,允許外中斷x中斷,EXx=0,禁止外中斷x中斷。(其中x=0.1)
4.IP
表4 IP中斷控制寄存器結構 | |||||||||
IP | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | |
- | - | - | PS | PT1 | PX1 | PT0 | PX0 | ||
位地址 | BCH | BBH | BAH | B9H | B8H |
IP叫做中斷優先級控制寄存器,其中的D0到D4的5位對應於5個優先級,對應次序如下:
PS:串行口中斷口優先級控制位,PS=1,串行口中斷聲明為高優先級中斷,PS=0,串行口定義為低優先級中斷。
PTx:定時器1優先級控制位。PTx=1,聲明定時器x為高優先級中斷,PTx=0定義定時器x為低優先級中斷。(其中x=0,1)
PXx:外中斷1優先級控制位。PTx=1,聲明外中斷x為高優先級中斷,PXx=0定義外中斷x為低優先級中斷。(其中x=0,1)
六、中斷實例: