一、中斷的基本概念
中斷程序一般指中斷服務(wù)程序。中斷服務(wù)程序,處理器處理“急件”,可理解為是一種服務(wù),是通過(guò)執(zhí)行事先編好的某個(gè)特定的程序來(lái)完成的,這種處理“急件”的程序被稱(chēng)為——中斷服務(wù)程序。在程序方面來(lái)說(shuō) 當(dāng)CPU在執(zhí)行一個(gè)程序的時(shí)候,突然產(chǎn)生了中斷事件CPU就去執(zhí)行中斷程序了,當(dāng)執(zhí)行完成后CPU又回來(lái)執(zhí)行原先的程序。
當(dāng)單片機(jī)正在執(zhí)行程序時(shí),出現(xiàn)了某些特殊狀況,例如定時(shí)時(shí)間到、有鍵盤(pán)信號(hào)輸入等,此時(shí)CPU須要暫時(shí)停止當(dāng)前的程序,而轉(zhuǎn)去執(zhí)行處理這些事件的程序,待執(zhí)行完這些特定的程序之后,再返回到原先的程序去執(zhí)行,這就形成了一次“中斷”。“中斷”加強(qiáng)了單片機(jī)處理突發(fā)事件的能力,如果沒(méi)有中斷功能,對(duì)可能發(fā)生的特殊狀況的處理就必須采用定時(shí)查詢,這樣就會(huì)浪費(fèi)大量的CPU時(shí)間。
因此,中斷是單片機(jī)中很重要的一個(gè)概念,是提高工作效率的重要功能,中斷系統(tǒng)功能的好壞是衡量單片機(jī)功能的重要指標(biāo)。單片機(jī)的“中斷源”與單片機(jī)包含的外圍設(shè)備有很大的關(guān)系,所謂“中斷源”就是引起中斷的原因或根源,就是中斷請(qǐng)求的來(lái)源。16F873/876內(nèi)部集成了12個(gè)外圍設(shè)備。
外圍設(shè)備在工作過(guò)程中,都需要CPU參與控制、協(xié)調(diào)或交換數(shù)據(jù)等服務(wù),而CPU正是通過(guò)中斷技術(shù)使得這些外圍設(shè)備協(xié)調(diào)工作的。PIC單片機(jī)作一次中斷處理的過(guò)程如下,當(dāng)某一中斷源發(fā)出中斷請(qǐng)求時(shí):
①假如CPU正在執(zhí)行更重要的任務(wù),則可采用屏蔽的方法暫時(shí)不響應(yīng)該中斷請(qǐng)求;
②如果可以響應(yīng)該中斷請(qǐng)求,則CPU執(zhí)行完當(dāng)前指令后,必須把斷點(diǎn)處的程序計(jì)數(shù)器PC的值(即下一條指令的地址)壓入堆棧保存起來(lái)(斷點(diǎn)保護(hù)),也可以把一些的重要寄存器內(nèi)容也保護(hù)起來(lái)(現(xiàn)場(chǎng)保護(hù))。然后再轉(zhuǎn)移到相應(yīng)的中斷服務(wù)子程序中執(zhí)行。
③在中斷服務(wù)子程序中,首先必須確定發(fā)出中斷請(qǐng)求的中斷源,然后再跳轉(zhuǎn)到與該中斷源相對(duì)應(yīng)的程序分支中去執(zhí)行中斷服務(wù)程序。
④當(dāng)中斷服務(wù)程序執(zhí)行畢后,必須先恢復(fù)被保護(hù)的寄存器的值(現(xiàn)場(chǎng)恢復(fù)),再將程序計(jì)數(shù)器PC的值從堆棧中恢復(fù)(斷點(diǎn)恢復(fù)) ,使CPU返回?cái)帱c(diǎn)處繼續(xù)執(zhí)行被中斷的程序。
二、中斷處理過(guò)程
(1)保護(hù)被中斷進(jìn)程現(xiàn)場(chǎng)。為了在中斷處理結(jié)束后能夠使進(jìn)程準(zhǔn)確地返回到中斷點(diǎn),系統(tǒng)必須保存當(dāng)前處理機(jī)程序狀態(tài)字PSW和程序計(jì)數(shù)器PC等的值。
(2)分析中斷原因,轉(zhuǎn)去執(zhí)行相應(yīng)的中斷處理程序。在多個(gè)中斷請(qǐng)求同時(shí)發(fā)生時(shí),處理優(yōu)先級(jí)最高的中斷源發(fā)出的中斷請(qǐng)求。
(3)恢復(fù)被中斷進(jìn)程的現(xiàn)場(chǎng),CPU繼續(xù)執(zhí)行原來(lái)被中斷的進(jìn)程。
三、中斷的運(yùn)用
1、設(shè)置中斷相關(guān)寄存器。這里包含了中斷源的方式(高、低、下降沿、上升沿),優(yōu)先級(jí)等,最后得開(kāi)啟當(dāng)前的中斷(可能有多個(gè)中斷),開(kāi)啟總中斷。設(shè)置完后,有中斷信號(hào)到來(lái)后,CPU就會(huì)處理了,自動(dòng)跳轉(zhuǎn)到中斷里去。
2、中斷服務(wù)函數(shù)。也就是CPU跳到中斷去,你想讓單片機(jī)干什么。比如之前的例子,開(kāi)門(mén)后,看是小廣告,我們不要,那關(guān)門(mén)。中斷服務(wù)函數(shù)就這樣,就是單片機(jī)跳過(guò)去需要處理的事情,一般是要求時(shí)效性的,緊急的事。
3、中斷嵌套。等會(huì)用一般的中斷后,再理解嵌套就簡(jiǎn)單了。
四、PIC16F876的中斷源
PIC16F876單片機(jī)具備的中斷源如下表所示:
從上表可看出,各中斷源基本上都與各個(gè)外圍設(shè)備模塊相對(duì)應(yīng)的:多數(shù)的外圍設(shè)備對(duì)應(yīng)著一個(gè)中斷源(如定時(shí)/計(jì)數(shù)器TMR0),也有的外圍設(shè)備對(duì)應(yīng)二個(gè)中斷源(如SCI同步/異步接收/發(fā)送器USART);有的外圍設(shè)備沒(méi)有中斷源與之對(duì)應(yīng)(如輸入/輸出端口 RA和RC);也有的中斷源沒(méi)有外圍設(shè)備與之對(duì)應(yīng)(例如外部中斷源INT)。
每一種中斷源對(duì)應(yīng)了一個(gè)中斷標(biāo)志位,記為XXXF,以及一個(gè)中斷屏蔽位或叫中斷使能位,記為XXXE。中斷源產(chǎn)生的中斷信號(hào)能否到達(dá)CPU,都受控于相應(yīng)的中斷屏蔽位。 每個(gè)中斷源申請(qǐng)中斷時(shí),其中斷標(biāo)志位會(huì)自動(dòng)置位,中斷標(biāo)志位的清0是由用戶程序完成的;而每個(gè)中斷屏蔽位的置位和清位均由用戶程序完成。
PIC16F876單片機(jī)的中斷系統(tǒng)的邏輯電路如圖:
圖中全部的的14個(gè)中斷源按兩個(gè)梯隊(duì)并列排開(kāi),第一梯隊(duì)中只安排了3個(gè)中斷源,其余的中斷源全部安排到第二梯隊(duì)中。所有的中斷源都受“全局中斷屏蔽位”(也稱(chēng)總屏蔽位)GIE的控制;第一梯隊(duì)的中斷源不僅受GIE的控制,還要受各自中斷屏蔽位的控制;第二梯隊(duì)的中斷源不僅受到GIE和各自中斷屏蔽位的控制,還要受到一個(gè)外設(shè)中斷屏蔽位PEIE的控制。
五、中斷相關(guān)的寄存器
與中斷有關(guān)的特殊功能寄存器SFR共有6個(gè),分別是:
選項(xiàng)寄存器OPTION_REG、中斷控制寄存器INTCON、第一外圍設(shè)備中斷標(biāo)志寄存器PIR1、第一外圍設(shè)備中斷屏蔽寄存器PIE1(也稱(chēng)中斷使能寄存器)、第二外圍設(shè)備中斷標(biāo)志寄存器PIR2和第二外圍設(shè)備中斷屏蔽寄存器PIE2。
后5個(gè)SFR,共有40位,但僅使用了30位來(lái)控制中斷,分別與圖中的中斷邏輯電路輸入信號(hào)成嚴(yán)格的對(duì)應(yīng)關(guān)系。
1、選項(xiàng)寄存器OPTION _REG
該寄存器包含了與定時(shí)/計(jì)數(shù)器TMR0、分頻器和端口RB有關(guān)的控制位。RB端口引腳RB0和外部中斷INT復(fù)用一腳,與該腳有關(guān)的一個(gè)控制位含義如下:
INTEDG:外部中斷INT觸發(fā)信號(hào)邊沿選擇位:1=選擇RB0/INT上升沿觸發(fā);0=選擇RB0/INT下降沿觸發(fā)。
2、中斷控制寄存器INTCON
它將第一梯隊(duì)中的3個(gè)中斷源的標(biāo)志位和屏蔽位,以及PEIE和GIE包含在其中:
RBIF:端口RB的引腳RB4~RB7電平變化中斷標(biāo)志位。1=RB4~RB7已經(jīng)發(fā)生了電平變化;0=RB4~RB7尚未發(fā)生電平變化。
RBIE:端口RB的引腳RB4~RB7電平變化中斷屏蔽位。1=允許RB產(chǎn)生的中斷;0=屏蔽端口RB產(chǎn)生的中斷。
INTF:外部INT引腳中斷標(biāo)志位。1=外部INT引腳有中斷觸發(fā)信號(hào); 0=外部INT引腳無(wú)中斷觸發(fā)信號(hào)。
INTE:外部INT引腳中斷屏蔽位。 l=允許外部INT引腳產(chǎn)生的中斷;0=屏蔽外部INT引腳產(chǎn)生的中斷。
T0IF:TMR0溢出中斷標(biāo)志位。1=TMR0已經(jīng)發(fā)生了溢出;0=TMR0尚未發(fā)生溢出。
T0IE:TMR0溢出中斷屏蔽位。1=允許TMR0溢出后產(chǎn)生的中斷; 0=屏蔽TMR0溢出后產(chǎn)生的中斷。
PEIE:外設(shè)中斷屏蔽位。1=允許CPU響應(yīng)來(lái)自第二梯隊(duì)中斷請(qǐng)求0=禁止CPU響應(yīng)來(lái)自第二梯隊(duì)中斷請(qǐng)求。
GIE:全局中斷屏蔽位(總屏蔽位)。1=允許CPU響應(yīng)所有中斷源產(chǎn)生的中斷請(qǐng)求;0=禁止CPU響應(yīng)所有中斷源產(chǎn)生的中斷請(qǐng)求。
3、 第一外圍設(shè)備中斷標(biāo)志寄存器PIR1
該寄存器中各中斷標(biāo)志位的含義如下:
TMR1IF:定時(shí)/計(jì)數(shù)器TMR1模塊溢出中斷標(biāo)志位。1=發(fā)生了TMR1溢出; 0=未發(fā)生TMR1溢出。
TMR2IF:定時(shí)/計(jì)數(shù)器TMR2模塊溢出中斷標(biāo)志位。1=發(fā)生了TMR2溢出; 0=未發(fā)生TMR2溢出。
CCP1IF:輸入捕捉/輸出比較/脈寬調(diào)制CCP1模塊中斷標(biāo)志位。 輸入捕捉模式下:1=發(fā)生了捕捉中斷請(qǐng)求;0=未發(fā)生捕捉中斷請(qǐng)求。輸出比較模式下:1=發(fā)生了比較輸出中斷請(qǐng)求;0=未發(fā)生比較輸出中斷請(qǐng)求。脈寬調(diào)制模式下: 無(wú)用。
SSPIF:同步串行端口(SSP)中斷標(biāo)志位。1=發(fā)送/接收完畢產(chǎn)生的中斷請(qǐng)求;0=等待發(fā)送/接收。
TXIF:串行通信接口(SCI)發(fā)送中斷標(biāo)志位。1=發(fā)送完成,即發(fā)送緩沖區(qū)空 0=正在發(fā)送,即發(fā)送緩沖區(qū)未空。
RCIF:串行通信接口(SCI)接收中斷標(biāo)志位。1=接收完成,即接收緩沖區(qū)滿0=正在接收,即接收緩沖區(qū)空。
ADIF:模擬/數(shù)字(A/D)轉(zhuǎn)換中斷標(biāo)志位。1=發(fā)生了A/D轉(zhuǎn)換中斷;0=未發(fā)生A/D轉(zhuǎn)換中斷。
PSPIF:并行端口中斷標(biāo)志位,只有40腳封裝型號(hào)具備,對(duì)于28腳封裝型號(hào)總保持0。1=并行端口發(fā)生了讀/寫(xiě)中斷請(qǐng)求;0=并行端口未發(fā)生讀/寫(xiě)中斷請(qǐng)求。
4、 第一外圍設(shè)備中斷屏蔽寄存器PIE1
該寄存器中包含的中斷屏蔽位(使能位)的含義如下:
TMR1IE:定時(shí)器/計(jì)數(shù)器TMRl模塊溢出中斷屏蔽位。l=開(kāi)放TMRl溢出發(fā)生中斷;0=屏蔽TMRl溢出發(fā)生中斷。
TMR2IE:定時(shí)/計(jì)數(shù)器TMR2溢出中斷屏蔽位。1=開(kāi)放TMR2溢出發(fā)生的中斷;0=屏蔽TMR2溢出發(fā)生的中斷。
CCP1IE:輸入捕捉/輸出比較/脈寬調(diào)制CCP1模塊中斷屏蔽位。1=開(kāi)放CCP1模塊產(chǎn)生的中斷請(qǐng)求;0=屏蔽CCP1模塊產(chǎn)生的中斷請(qǐng)求。
SSPIE:同步串行端口(SSP)中斷屏蔽位。1=開(kāi)放SSP模塊產(chǎn)生的中斷請(qǐng)求0=屏蔽SSP模塊產(chǎn)生的中斷請(qǐng)求。
TXIE:串行通信接口(SCI)發(fā)送中斷屏蔽位。1=開(kāi)放SCI發(fā)送中斷請(qǐng)求;0=屏蔽SCI發(fā)送中斷請(qǐng)求。
RCIE:串行通信接口(SCI)接收中斷屏蔽位。1=開(kāi)放SCI接收中斷請(qǐng)求;0=屏蔽SCI接收中斷請(qǐng)求。
ADIE:模擬/數(shù)字(A/D)轉(zhuǎn)換中斷屏蔽位。1=開(kāi)放A/D轉(zhuǎn)換器的中斷請(qǐng)求;0=屏蔽A/D轉(zhuǎn)換器的中斷請(qǐng)求。
PSPIE:并行端口中斷屏蔽位,只有40腳封裝型號(hào)具備,對(duì)于28腳封裝型號(hào)總保持0。1=開(kāi)放并行端口讀/寫(xiě)發(fā)生的中斷請(qǐng)求;0=屏蔽并行端口讀/寫(xiě)發(fā)生的中斷請(qǐng)求。
5、 第二外圍設(shè)備中斷標(biāo)志寄存器PIR2
CCP2IF:輸入捕捉/輸出比較/脈寬調(diào)制CCP2模塊中斷標(biāo)志位。輸入捕捉模式下:1=發(fā)生了捕捉中斷請(qǐng)求(必須用軟件清0);0=未發(fā)生捕捉中斷請(qǐng)求。輸出比較模式下:1=發(fā)生了比較輸出中斷請(qǐng)求(必須用軟件清0);0=未發(fā)生比較輸出中斷請(qǐng)求。脈寬調(diào)制模式下:無(wú)用
BCLIF:I2C總線沖突中斷標(biāo)志。當(dāng)同步串行端口MSSP被配置成I2C總線的主控器模式時(shí):1=發(fā)生了總線沖突;0=未發(fā)生總線沖突。
EEIF:EEPROM寫(xiě)操作中斷標(biāo)志位。1=寫(xiě)操作已經(jīng)完成(必須用軟件清0);0=寫(xiě)操作未完成或尚未開(kāi)始進(jìn)行。
6、 第二外圍設(shè)備中斷屏蔽寄存器PIE2
CCP2IE:輸入捕捉/輸出比較/脈寬調(diào)制CCP2模塊中斷屏蔽位。1=開(kāi)放CCP2模塊產(chǎn)生的中斷請(qǐng)求;
0=屏蔽CCP2模塊產(chǎn)生的中斷請(qǐng)求。
EEIE:EEPROM寫(xiě)操作中斷屏蔽位。1=開(kāi)放EEPROM寫(xiě)操作產(chǎn)生的中斷請(qǐng)求;0=屏蔽EEPROM寫(xiě)操作產(chǎn)生的中斷請(qǐng)求。
六、PIC單片機(jī)timer中斷實(shí)例
功能描述: Timer0實(shí)現(xiàn)1s定時(shí),RD低四位取反控制LED低四位,Timer1實(shí)現(xiàn)0.5s定時(shí),RD高四位取反控制LED高四位
維護(hù)記錄: 2011-8-22
***************************************************************************************************/
#include 《pic.h》 //頭文件在HI-TECH安裝目錄下\HI-TECH Software\PICC\std\9.60\include
#define uchar unsigned char
#define uint unsigned int
uint temp1,temp2;
//***********************************************************************************
//延時(shí)
//***********************************************************************************
void delay(uint time)
{
uint i,j;
for(i = 0;i 《 time; i++)
{
for(j = 0;j 《 30; j++);
}
}
//***********************************************************************************
//IO初始化操作
//***********************************************************************************
void IO_init(void)
{
TRISD=0x00; //RD設(shè)置為輸出
PORTD=0xff; //初始化為高
}
//***********************************************************************************
//timer0初始化
//***********************************************************************************
void timer0_init(void) //fosc/4=4M/4所以計(jì)數(shù)周期為1us
{
T0CS=0; //timer0工作于定時(shí)器方式
PSA=1; //timer0不分頻
T0IF=0; //清timer0中斷標(biāo)志
T0IE=1; //timer0中斷允許
TMR0=0xAA; /*置初值,定時(shí)100us。因?yàn)閷?xiě)入TMR0后接著的兩個(gè)周期不能增量,
中斷需要3個(gè)周期的響應(yīng)時(shí)間,以及C語(yǔ)言自動(dòng)進(jìn)行現(xiàn)場(chǎng)保護(hù)要消
耗周期,取修正值15,所以只需要定時(shí)100-15=85us
初值=255-85=0xaa*/
GIE=1; //開(kāi)總中斷
}
//***********************************************************************************
//timer1初始化
//***********************************************************************************
void timer1_init(void) //fosc/4=4M/4所以計(jì)數(shù)周期為1us
{
T1CON=0X01; //16位定時(shí)方式
TMR1IF=0; //清timer1中斷標(biāo)志
TMR1IE=1; //timer1中斷允許
TMR1H=0xFC; /*置初值,TMR1每1ms中斷一次。因?yàn)閷?xiě)入TMR1后接著的兩個(gè)周期不能增量,
中斷需要3個(gè)周期的響應(yīng)時(shí)間,以及C語(yǔ)言自動(dòng)進(jìn)行現(xiàn)場(chǎng)保護(hù)要消
耗周期,取修正值15,所以只需要定時(shí)1000-15=985us
初值=65535-985=0xFC26*/
TMR1L=0x26;
PEIE=1; //允許外圍中斷
GIE=1; //開(kāi)總中斷
}
//*************************************************
**********************************
//中斷服務(wù)子程序
//***********************************************************************************
void interrupt ISR(void)
{
// Timer0 interrupt service routine
if(TMR0IF==1)
{
TMR0=0xAA; //每100us中斷一次對(duì)TMR0寫(xiě)入一個(gè)調(diào)整值。
T0IF=0; //清timer0中斷標(biāo)志
temp1++; //中斷次數(shù)加1
if(temp1》9999) //中斷10000次后,為1秒
{
temp1=0; //中斷次數(shù)清0
RD0=!RD0;RD1=!RD1; RD2=!RD2; RD3=!RD3;//取反控制RD低4位LED發(fā)光或熄滅
}
}
// Timer1 interrupt service routine
if(TMR1IF==1)
{
TMR1H=0XFC; //中斷一次對(duì)TMR1寫(xiě)入一個(gè)調(diào)整值。
TMR1L=0x26;
TMR1IF=0; //清timer1中斷標(biāo)志
temp2++; //中斷次數(shù)加1
if(temp2》499) //中斷500次后,為0.5秒
{
temp2=0; //中斷次數(shù)清0
RD4=!RD4; RD5=!RD5; RD6=!RD6; RD7=!RD7; //取反控制RD高4位LED發(fā)光或熄滅
}
}
}
//***********************************************************************************
//主函數(shù)
//***********************************************************************************
main()
{
__CONFIG(XT&WDTDIS&LVPDIS); //配置,設(shè)置為晶振XT方式振蕩,禁看門(mén)狗,禁低電壓編程
IO_init(); //IO初始化
timer0_init(); //定時(shí)器0初始化
timer1_init(); //定時(shí)器1初始化
while(1); //死循環(huán)
}
//******************************************程序結(jié)束*****************************************
評(píng)論
查看更多