INT0,INT1,TF0,TF1,RI/TI這5個(gè)中斷源在單片機(jī)中稱(chēng)為:外部中斷0,外部中斷1,Timer0中斷,Timer1中斷,串行通信中斷。
一,中斷實(shí)例和中斷的控制者
例:什么是中斷
開(kāi)關(guān)中斷產(chǎn)生后,出現(xiàn)綠燈閃一下,紅燈閃一下。
程序:
ORG 00H; 起始行號(hào)00H
MAIN: ; MAIN以下是主程序段,點(diǎn)亮綠色LED——D1
MOV IE, #84H;使能外部中斷1,
GREEN:
CLR P0.0; 點(diǎn)亮綠色LED——D1
JMP GREEN; 循環(huán)
ORG 13H; 中斷服務(wù)子程序起始地址為13H
EXT1_RED:
SETB P0.0; 熄滅綠色LED——D1
CLR P0.1; 點(diǎn)亮紅色LED——D2
D1: MOV R4, #200; 延時(shí)程序100ms
D2: MOV R5, #248;
DJNZ R5,$; R5的值減少1,等于0就往下執(zhí)行,否則反復(fù)執(zhí)行本行
DJNZ R4,D2; R4的值減少1,等于0就往下執(zhí)行,否則跳轉(zhuǎn)到D2標(biāo)號(hào)處執(zhí)行
SETB P0.1; 熄滅紅色LED——D2
RETI; 中斷服務(wù)子程序結(jié)束
END; 程序結(jié)束
二,中斷服務(wù)的指揮官--中斷向量表(AT89S51)
中斷向量表,向量即“取向”的意思 ,例如外部中斷0發(fā)生時(shí),單片機(jī)會(huì)到程序存儲(chǔ)器的003H中尋找中斷服務(wù)子程序來(lái)執(zhí)行。
中斷源 向量地址 中斷標(biāo)志位 對(duì)應(yīng)管腳
外部中斷(INT0)管腳 0003H IE0 P3.2
Timer0中斷 000BH TF0 P3.4
外部中斷(INT1)管腳 0013H IE1 P3.3
Timer1中斷 001BH TF1 P3.5
串行通信中斷 0023H TI/RI TI(P3.1)
RI(P3.0)
三,中斷響應(yīng)和處理過(guò)程
1)立即暫停正在執(zhí)行的任何程序,并把下一條要執(zhí)行的指令地址壓入堆棧中。
2)保存所有中斷狀態(tài)(但不在堆棧中)
3)根據(jù)中斷向量表找到中斷對(duì)應(yīng)的地址。
4)單片機(jī)到該地址上開(kāi)始執(zhí)行中斷服務(wù)子程序,直到遇到指令RETI為止。
5)遇到RETI指令后,從堆棧中彈出在中斷產(chǎn)生時(shí)保存的將要執(zhí)行的下一條指令的地址到程序計(jì)數(shù)器PC中,單片機(jī)開(kāi)始執(zhí)行從PC指示的地址繼續(xù)執(zhí)行程序。
6)問(wèn)題:每一個(gè)中斷服務(wù)子程序的存放空間都很有限,例如,外部中斷0的中斷向量為0003H,而Timer0中斷量地址為000BH,可見(jiàn)外部中斷0的中斷服務(wù)子程序只有0003H~000AH這8個(gè)字節(jié)的空間來(lái)存放,這8個(gè)字節(jié)的空間實(shí)在也放不了幾條指令。
如果單片機(jī)使能了多個(gè)中斷,并且每一個(gè)中斷服務(wù)子程序都按中斷向量表中的地址開(kāi)始存放,就很有可能出現(xiàn)一個(gè)中斷服務(wù)子程序占據(jù)其他服務(wù)子程序空間的問(wèn)題。
★★★解決問(wèn)題辦法:用JMP指令跳轉(zhuǎn)到別處開(kāi)始執(zhí)行。
例:
ORG 00H; 起始地址00H
JMP MAIN; 跳轉(zhuǎn)到MAIN
ORG 03H; 外部中斷0的起地址03H
JMP EXT0; 跳轉(zhuǎn)到EXT0
ORG 0BH; Timer0中斷0的起地址0BH
JMP TIM0; 跳轉(zhuǎn)到TIM0
ORG 013H; 外部中斷1的起地址013H
JMP LOOP; 跳轉(zhuǎn)到LOOP
ORG 01BH; Timer1中斷0的起地址0BH
JMP LOAD; 跳轉(zhuǎn)到LOAD
ORG 023H; 串行口通信中斷RI/TI的起地址023H
JMP START; 跳轉(zhuǎn)到START
四,中斷的控制者--中斷使能寄存器IE
單片機(jī)上電復(fù)位之后,默認(rèn)所有中斷都被關(guān)閉。為了使單片機(jī)能對(duì)中斷進(jìn)行響應(yīng),需要對(duì)中斷使能寄存器IE進(jìn)行操作。
IE的初始化過(guò)程即是使用MOV指令向其載入控制字。
7 6 5 4 3 2 1 0
EA 保留 保留 ES ET1 EX1 ET0 EX0
EA中斷使能; ET1 Timer1中斷使能;
保留(不要訪問(wèn)該位); EX1 外部中斷1使能;
ES串行口中斷使能; ET0 Timer0中斷使能;
EX0 外部中斷0使能;
五,外部中斷的電平觸發(fā)
1) 在使能中斷后,如果在INT0和INT1口上出現(xiàn)低電平就會(huì)觸發(fā)外部中斷0或外部中斷1, 單片機(jī)會(huì)立即停止正在執(zhí)行的程序,執(zhí)行中斷服務(wù)子程序,是單片機(jī)復(fù)位之后的外部中斷默認(rèn)觸發(fā)方式。
2)在單片機(jī)進(jìn)入執(zhí)行中斷服務(wù)子程序時(shí),在執(zhí)行到中斷服務(wù)子程序結(jié)束指令RETI之前,這樣低電平必須撤走,否則將會(huì)使單片機(jī)執(zhí)行完RETI指令后再次進(jìn)入中斷服務(wù)子程序。
3)外部中斷的(Tdp)電平觸發(fā)--一般為了保證外部中斷的產(chǎn)生,低電平的時(shí)長(zhǎng)到少需要4個(gè)機(jī)器周期,若晶振是12MHZ,則一個(gè)機(jī)器周期是一微秒,4個(gè)機(jī)器周期就是4微秒。
低電平觸發(fā)外部中斷的保持時(shí)間至少要大于或等于4微秒。(Tdp≥4us)
4)外部中斷的(Tby)邊沿觸發(fā)---至少一個(gè)機(jī)器周期的高電平,且向低電平跳變之后至少保持1個(gè)機(jī)器周期,如晶振為12MHz,則一個(gè)周期的高電平和一個(gè)機(jī)器周期的低電平。(Tby≥1us)
5)外部中斷的(Tby)邊沿觸發(fā)---需要指令來(lái)設(shè)置寄存器TCON。
7 6 5 4 3 2 1 0
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
7654與定時(shí)/計(jì)數(shù)器有關(guān)。
IE1外部中斷1邊沿標(biāo)志位; IE0外部中斷0邊沿標(biāo)志位;
IT1外部中斷1方式控制位; IT0外部中斷0方式控制位;
(IT1清0 ,電平觸發(fā)//置1,邊沿觸發(fā)) (IT0清0 ,電平觸發(fā)//置1,邊沿觸發(fā))
6)外部中斷的(Tdp)電平觸發(fā)//(Tby)邊沿觸發(fā)特點(diǎn):
①電平觸發(fā)方式下,若按下開(kāi)關(guān)S不放,端口將不斷獲得低電平,中斷不斷產(chǎn)生,中斷服務(wù)子程序被重復(fù)執(zhí)行;
②邊沿觸發(fā)方式下,只對(duì)端口的電平跳變有反應(yīng),若也不放開(kāi)開(kāi)關(guān)S,并不會(huì)連續(xù)地產(chǎn)生中斷。
③電平觸發(fā)方式下,若單片機(jī)正在執(zhí)行中斷服務(wù)子程序時(shí),外部中斷再次發(fā)生,電平觸發(fā)信號(hào)不會(huì)被鎖存,所以單片機(jī)不會(huì)響應(yīng)第二次中斷。而在邊沿觸發(fā)方式下有所不同,單片機(jī)正在執(zhí)行中斷服務(wù)子程序,如果中斷發(fā)生,電平跳變產(chǎn)生的中斷觸發(fā)信號(hào)保存在TCON寄存器中的IE0或IE1中,單片機(jī)再次檢測(cè)到IE0或IE1,又進(jìn)入中斷服務(wù)子程序中。
注意:在單片機(jī)正在執(zhí)行中斷服務(wù)子程序時(shí),電平觸發(fā)方式會(huì)(★漏掉★)新的中斷,而邊沿觸發(fā)方式會(huì)(★保留★)新的中斷。
7)★問(wèn)題★:前面通過(guò)檢測(cè)Tmier溢出標(biāo)志位TFx來(lái)判斷計(jì)時(shí)是否完成。在判斷的過(guò)程中,單片機(jī)除了循環(huán)判斷之外一般不做任何操作,如果在計(jì)時(shí)的同時(shí)又需要執(zhí)行別的程序該怎么辦呢?
★解決辦法:當(dāng)通過(guò)中斷使能寄存器IE使能Tmier中斷,設(shè)置好Tmier的工作參數(shù),啟動(dòng)Tmier之后,單片機(jī)就可以去做別的操作。Tmier溢出時(shí),單片機(jī)將會(huì)自動(dòng)停下正在執(zhí)行的任何程序而進(jìn)入Tmier中斷服務(wù)子程序中執(zhí)行。
兩個(gè)中斷的中斷向量地址分別為00BH和001BH。
★★★★★例:利用Tmier0中斷產(chǎn)生50HZ方波信號(hào)(★此程序有錯(cuò)誤,高電平有0.02秒,低電平無(wú)法保持0.02秒以上)
程序:
ORG 00H; 起始地址00H
JMP MAIN; 跳轉(zhuǎn)到MAIN
ORG 0BH; Tmier0中斷服務(wù)子程序起始地址為0BH
JMP TIM_LOW; 跳轉(zhuǎn)到TIM_LOW
; 下面是主程序段,初始化
MAIN:
MOV IE,#82H; 使能Tmier0中斷(10000010B)
MOV TMOD,#01H; 設(shè)置Tmier0工作在模式1下
TIMER0_LOAD:
MOV TH0,#0B1H; 往TH0中載入計(jì)數(shù)初始值(65536-20000=45536)0.02秒
MOV TL0,#0E0H; 往TL0中載入計(jì)數(shù)初始值(45536=B1E0,則:TH0=B1H,TL0=E0H)
SETB TR0; 使TR0置1,以啟動(dòng)Tmier0
SET_HIGH:
SETB P1.0; p1.0=1
JMP SET_HIGH; 循環(huán)
TIM_LOW:
CLR P1.0; P1.0=0
MOV TH0,#0B1H; 重新往TH0中載入計(jì)數(shù)初始值
MOV TL0,#0E0H; 重新往TL0中載入計(jì)數(shù)初始值
RETI; 中斷服務(wù)子程序結(jié)束
END; 程序結(jié)束