天堂草原最受欢迎的角色,天堂动漫,天堂在线,色天堂下载,天堂中文在线资源,亚洲男人天堂

技術(shù)熱線: 4007-888-234
設(shè)計(jì)開(kāi)發(fā)

專注差異化嵌入式產(chǎn)品解決方案 給智能產(chǎn)品定制注入靈魂給予生命

開(kāi)發(fā)工具

提供開(kāi)發(fā)工具、應(yīng)用測(cè)試 完善的開(kāi)發(fā)代碼案例庫(kù)分享

技術(shù)支持

從全面的產(chǎn)品導(dǎo)入到強(qiáng)大技術(shù)支援服務(wù) 全程貼心伴隨服務(wù),創(chuàng)造無(wú)限潛能!

新品推廣

提供新的芯片及解決方案,提升客戶產(chǎn)品競(jìng)爭(zhēng)力

新聞中心

提供最新的單片機(jī)資訊,行業(yè)消息以及公司新聞動(dòng)態(tài)

PIC16F87X單片機(jī)中斷系統(tǒng)應(yīng)用須關(guān)注的問(wèn)題

更新時(shí)間: 2019-03-22
閱讀量:2774

摘要:美國(guó)微芯公司研制的PIC系列單片機(jī),其硬件結(jié)構(gòu)和指令系統(tǒng)采用了與眾不同的設(shè)計(jì)手法。在架構(gòu)上和概念上對(duì)傳統(tǒng)單片機(jī)進(jìn)行了一些突破性的變革,但也給這類單片機(jī)的應(yīng)用帶來(lái)了一些特殊問(wèn)題。本文針對(duì)PIC16F87X系列單片機(jī)中斷的特點(diǎn),及其在應(yīng)用過(guò)程中應(yīng)該注意的幾個(gè)問(wèn)題進(jìn)行必要的說(shuō)明。內(nèi)容包括中斷源、中斷邏輯、中斷相關(guān)的寄存器、中斷的延時(shí)、中斷的現(xiàn)場(chǎng)保護(hù)以及注意事項(xiàng)等。 四、 中斷的處理

前在世界一些著名的單片機(jī)產(chǎn)品系列中,PIC16F87X系列單片機(jī)是芯片內(nèi)部包含有外圍設(shè)備模塊數(shù)量最多的單片機(jī)品種之一。PIC16F874和PIC16F877單片機(jī)的芯片內(nèi)部集成了15個(gè)外圍設(shè)備模塊;PIC16F873和PIC16F876單片機(jī)的芯片內(nèi)部集成了12個(gè)外圍設(shè)備模塊。在最近推出的該系列的新型號(hào)中, PIC16F870單片機(jī)的芯片內(nèi)部集成了10個(gè)外圍設(shè)備模塊;PIC16F871單片機(jī)的芯片內(nèi)部集成了13個(gè)外圍設(shè)備模塊;PIC16F872單片機(jī)的芯片內(nèi)部也集成了10個(gè)外圍設(shè)備模塊(比PIC16F870多了1個(gè)USART模塊,少了1個(gè)SSP模塊)。 

  這些外圍設(shè)備模塊在啟用時(shí)以及在工作過(guò)程中,都或多或少地需要CPU參與控制、協(xié)調(diào)或交換數(shù)據(jù)等各種服務(wù)工作。由于CPU的運(yùn)行速度非常高,而各個(gè)外圍設(shè)備模塊的工作速度卻非常低,況且這些外圍設(shè)備模塊也不是頻繁地要求CPU對(duì)其服務(wù)。因此,通常采取一種讓眾多外圍設(shè)備模塊共享1個(gè)CPU,并且能夠及時(shí)得到CPU服務(wù)的調(diào)度方法——中斷。 

一、 PIC16F87X的中斷源

  PIC系列單片機(jī)是當(dāng)今世界上很有影響力的精簡(jiǎn)指令集(RISC)微控制器,具有豐富的中斷功能。其中功能強(qiáng)大的中、高擋型號(hào)的中斷源有18種之多。在PIC單片機(jī)家族中,排位屬于中上水平的PIC16F87X子系列單片機(jī)具備的中斷源多達(dá)14種。其中,單片機(jī)的型號(hào)不同,中斷源的種類、個(gè)數(shù)也不同,如表1所列。其不足之處是:中斷矢量只有1個(gè),并且各個(gè)中斷源之間也沒(méi)有優(yōu)先級(jí)別之分,不具備非屏蔽中斷。 

表1 PIC16F87X單片機(jī)的中斷源及其數(shù)量

中斷源種類

中斷源志位

中斷源蔽位

873/ 876

874/ 877

870

871

872

外部觸發(fā)中斷INT

INTF

INTE

TMR0溢出中斷

T0IF

T0IE

RB端口電平變化中斷

RBIF

RBIE

TMR1溢出中斷

TMR1IF

TMR1IE

TMR2中斷

TMR2IF

TMR2IE

CCP1中斷

CCP1IF

CCP1IE

CCP2中斷

CCP2IF

CCP2IE




SCI同步發(fā)送中斷

TXIF

TXIE


SCI同步接收中斷

RCIF

RCIE


SSP中斷

SSPIF

SSPIE



SSP I2C總線碰撞中斷

BCLIF

BCLIE



并行端口中斷

PSPIF

PSPIE




A/D轉(zhuǎn)換中斷

ADIF

ADIE

E2PROM中斷

EEIF

EEIE




13種

14種

10種

11種

10種

從表1中可以看出,各中斷源基本上都是與各個(gè)外圍設(shè)備模塊相對(duì)應(yīng)的。其中,多數(shù)外圍設(shè)備模塊對(duì)應(yīng)著1個(gè)中斷源(比如定時(shí)器/計(jì)數(shù)器TMR0模塊),有的外圍設(shè)備模塊對(duì)應(yīng)著2個(gè)中斷源(比如通用同步/接收/發(fā)送器SCI模塊),也有的外圍設(shè)備模塊沒(méi)有中斷源與之對(duì)應(yīng)(比如輸入/輸出端口RA和RC模塊),還有的中斷源沒(méi)有外圍設(shè)備模塊與之對(duì)應(yīng)(比如外部觸發(fā)中斷源INT)。 

二、 PIC16F87X的中斷硬件邏輯

  在PIC16F87X的子系列中,具體型號(hào)不同,中斷邏輯電路也存在著差異,中斷源的種類和個(gè)數(shù)也不同:最多的具備14種中斷源;最少的具備10種中斷源(詳見(jiàn)表1)。其中并行端口模塊和并行端口中斷源,只有40腳封裝的型號(hào)(PIC16F871、PIC16F874和PIC16F877)才會(huì)具備;而對(duì)于28腳封裝的型號(hào)(PIC16F870、PIC16F872、PIC16F873和PIC16F876)則不具備。
  PIC16F87X系列單片機(jī)中斷系統(tǒng)的邏輯電路如圖1所示。每一種中斷源對(duì)應(yīng)著1個(gè)中斷標(biāo)志位(記為XXXF,F(xiàn)是Flag的第1個(gè)英文字母)和1個(gè)中斷屏蔽位或者叫中斷使能位(記為XXXE,E是Enable的第1個(gè)英文字母)。中斷源產(chǎn)生的中斷標(biāo)志信號(hào)是否得以向前傳遞,將受控于對(duì)應(yīng)的中斷屏蔽位。每一個(gè)中斷標(biāo)志位都對(duì)應(yīng)著1個(gè)觸發(fā)器。當(dāng)中斷源申請(qǐng)CPU中斷時(shí),與之對(duì)應(yīng)的觸發(fā)器就由硬件自動(dòng)置位,而該觸發(fā)器的清零是由用戶安排程序來(lái)實(shí)現(xiàn)的;每一個(gè)中斷屏蔽位也對(duì)應(yīng)著1個(gè)觸發(fā)器。該觸發(fā)器的置位和清零均是由用戶程序完成的。
  圖1描繪的邏輯電路是1個(gè)由簡(jiǎn)單的門電路構(gòu)成的組合邏輯電路。將全部14個(gè)中斷源按2個(gè)梯隊(duì)并列排開(kāi),第1梯隊(duì)中只安排了3個(gè)中斷源,其余的中斷源全部安排到第2梯隊(duì)中。這樣做是為了與早期的PIC系列單片機(jī)型號(hào)相兼容(前些年研制出的單片機(jī)型號(hào)片內(nèi)配置的外圍設(shè)備模塊數(shù)量較少,相應(yīng)的中斷源的數(shù)量自然也就少,比如PIC16C61只有第1梯隊(duì)中的3個(gè)中斷源)。近期研制的一些PIC單片機(jī)新型號(hào)是在原有的單片機(jī)芯片基礎(chǔ)之上進(jìn)行一些功能擴(kuò)展而得來(lái)的。 

所有的中斷源都受全局中斷屏蔽位(也可以稱為總屏蔽位)GIE的控制。第1梯隊(duì)的中斷源不僅受全局中斷屏蔽位的控制,還要受各自中斷屏蔽位的控制;第2梯隊(duì)的中斷源不僅受到全局中斷屏蔽位和各自中斷屏蔽位的控制,還要額外受到1個(gè)外設(shè)中斷屏蔽位PEIE的控制。

三、 中斷相關(guān)的寄存器

  與中斷功能有關(guān)的特殊功能寄存器共有5個(gè):中斷控制寄存器INTCON、第1外圍設(shè)備中斷標(biāo)志寄存器PIR1、第1外圍設(shè)備中斷屏蔽寄存器(又稱中斷使能寄存器)PIE1、第2外圍設(shè)備中斷標(biāo)志寄存器PIR2和第2外圍設(shè)備中斷屏蔽寄存器PIE2。如表2所列,5個(gè)寄存器中共有40位,其中使用了30位。分別與圖1中的中斷邏輯電路的輸入邏輯信號(hào)成嚴(yán)格對(duì)應(yīng)關(guān)系,也與邏輯表達(dá)式成嚴(yán)格對(duì)應(yīng)關(guān)系。這5個(gè)寄存器都具有在RAM數(shù)據(jù)存儲(chǔ)器中統(tǒng)一編碼的地址。也就是說(shuō),PIC單片機(jī)可以把這5個(gè)特殊寄存器當(dāng)作普通寄存器單元來(lái)訪問(wèn)(即讀出或?qū)懭氩僮鳎_@樣有利于減少指令集的指令類型和指令數(shù)量,也便于學(xué)習(xí)、記憶和編程。

  單片機(jī)復(fù)位后,由硬件自動(dòng)對(duì)全局中斷屏蔽位進(jìn)行設(shè)置GIE=0,將屏蔽所有的中斷源。中斷返回指令“RETFIE”執(zhí)行后,也由硬件自動(dòng)對(duì)總屏蔽位進(jìn)行設(shè)置GIE=1,重新開(kāi)放所有的中斷源。不論各種中斷屏蔽位和全局中斷屏蔽位GIE處于何種狀態(tài)(是開(kāi)放還是禁止),當(dāng)某一中斷源的中斷條件滿足時(shí),都會(huì)發(fā)出中斷請(qǐng)求,相應(yīng)的中斷標(biāo)志位都會(huì)被置位(=1)。但是,是否能夠得到CPU的響應(yīng),則要根據(jù)該中斷源所涉及到的中斷屏蔽位的狀態(tài)而定。CPU響應(yīng)中斷后,由硬件自動(dòng)對(duì)全局中斷屏蔽位進(jìn)行清零(GIE=0),屏蔽所有的中斷源,以免發(fā)生重復(fù)中斷響應(yīng),然后,由硬件自動(dòng)把當(dāng)前的程序計(jì)數(shù)器PC值(即程序斷點(diǎn)地址)壓入堆棧(實(shí)際為硬件堆棧),并且把PC寄存器置以中斷向量地址(0004H),從而轉(zhuǎn)向并開(kāi)始執(zhí)行中斷服務(wù)程序。進(jìn)入中斷服務(wù)程序后,程序中必須安排指令,檢查發(fā)出請(qǐng)求的中斷源(如果同時(shí)開(kāi)放多個(gè)中斷源的話)。這可以通過(guò)檢查各個(gè)中斷源的標(biāo)志位來(lái)實(shí)現(xiàn)。一旦確定出發(fā)出申請(qǐng)的中斷源,就用軟件把該中斷源的標(biāo)志位人為地清零,否則,執(zhí)行中斷返回指令“RETFIE”。重開(kāi)中斷后,由于中斷標(biāo)志位仍為“1”而引起CPU重復(fù)響應(yīng)同一個(gè)中斷請(qǐng)求。中斷服務(wù)程序的末尾必須放置1條中斷返回指令“RETFIE”。執(zhí)行該條指令后,不僅可以重開(kāi)中斷,而且還可以由硬件自動(dòng)將保留在堆棧頂部的斷點(diǎn)地址彈出,并放回到程序計(jì)數(shù)器PC中,使CPU返回和繼續(xù)執(zhí)行被中斷的主程序。 

1 中斷的延時(shí)響應(yīng)和延時(shí)處理
  1次中斷過(guò)程,從中斷源發(fā)出請(qǐng)求到得到CPU的響應(yīng)必然存在一定的延遲時(shí)間。

 在圖2中,第1行是系統(tǒng)時(shí)鐘脈沖信號(hào),每4個(gè)時(shí)鐘周期對(duì)應(yīng)1個(gè)指令周期。第2行就是指令周期信號(hào)。該信號(hào)只有在RC振蕩模式下,從OSC2腳上可以向片外送出。第3行是單片機(jī)外部引腳INT送入的中斷脈沖信號(hào)。外部中斷信號(hào)INT是用邊沿觸發(fā)的。假設(shè)預(yù)先設(shè)定的是INT中斷信號(hào)上升沿有效的話,則該信號(hào)的上升沿將會(huì)在1個(gè)時(shí)鐘周期后引發(fā)中斷標(biāo)志位INTF被置位。第4行代表INTF信號(hào)。每個(gè)指令周期內(nèi)的第2個(gè)時(shí)鐘脈沖上升沿時(shí),該信號(hào)被抽檢1次。一旦檢測(cè)到INTF信號(hào)被設(shè)置為“1”,則CPU會(huì)在接下來(lái)的1個(gè)指令周期內(nèi),將全局中斷屏蔽位GIE清零。第5行是全局中斷屏蔽位GIE。在GIE信號(hào)被清零的下一個(gè)指令周期內(nèi),程序計(jì)數(shù)器PC被置入中斷向量0004H,見(jiàn)圖2中第6行。同時(shí)在該指令周期內(nèi)完成到中斷服務(wù)程序的跳轉(zhuǎn),并且實(shí)現(xiàn)提取該子程序的首條指令,即指令(0004H),見(jiàn)圖2中第7行。在其后的1個(gè)指令周期內(nèi),正式開(kāi)始執(zhí)行中斷服務(wù)程序的第1條指令,見(jiàn)圖2中第8行。自INT引腳輸入有效信號(hào),到中斷服務(wù)程序的第1條指令得到執(zhí)行,大約需要3~4個(gè)指令周期的延時(shí)。更精確的延遲時(shí)間取決于中斷事件的發(fā)生時(shí)機(jī)。
  以上描述的只是1次中斷從申請(qǐng)到得到CPU的響應(yīng)的延遲時(shí)間。下面分析從CPU響應(yīng)1次中斷到該中斷得到有效處理的延遲時(shí)間。由于具有中斷功能的PIC系列單片機(jī)(低檔產(chǎn)品PIC16C5X和PIC12C5X系列不具備中斷功能),采用的是“多源中斷”的設(shè)計(jì)方案(即1個(gè)中斷向量對(duì)應(yīng)著多個(gè)中斷源),只有惟一的1個(gè)中斷向量,或者說(shuō)只有1個(gè)中斷服務(wù)程序入口地址。這就意味著,此類單片機(jī)的中斷服務(wù)程序只能編寫1個(gè)。這類單片機(jī)的硬件結(jié)構(gòu)得到了簡(jiǎn)化,那么,相應(yīng)的軟件設(shè)計(jì)上就得多開(kāi)銷一些。在1個(gè)中斷服務(wù)程序中,若想對(duì)多個(gè)中斷源作出處理,就必須在進(jìn)入中斷服務(wù)程序后,首先執(zhí)行調(diào)查具體中斷源的一條或多條指令,其后才能對(duì)查到的中斷源作出有針對(duì)性的服務(wù)。如此以來(lái),就形成了1次中斷從CPU響應(yīng)到進(jìn)入針對(duì)性處理的延遲時(shí)間。該時(shí)間有長(zhǎng)有短,它會(huì)隨著被開(kāi)放的中斷源的個(gè)數(shù)的增加而增加。最好情況是只有1個(gè)中斷源被開(kāi)放,這時(shí)不需要檢測(cè)中斷源就可以立即進(jìn)入針對(duì)性處理;最壞情況是所有中斷源全部開(kāi)放,此時(shí)用在檢測(cè)中斷源上的時(shí)間會(huì)最長(zhǎng)。
  另外,PIC單片機(jī)中采用的是硬件堆棧結(jié)構(gòu)。其好處是既不占用程序存儲(chǔ)器

空間,也不占用數(shù)據(jù)存儲(chǔ)器空間,同時(shí)也不需用戶去操作堆棧指針;但此時(shí)也帶來(lái)1個(gè)不可回避的弱點(diǎn),即不具備像其他單片機(jī)指令系統(tǒng)中的壓棧(PUSH)和出棧(POP)指令那樣,實(shí)現(xiàn)中斷現(xiàn)場(chǎng)的保護(hù)會(huì)麻煩一些,并且占用的處理時(shí)間也相應(yīng)多一點(diǎn)。
  2 中斷的現(xiàn)場(chǎng)保護(hù)問(wèn)題
  中斷現(xiàn)場(chǎng)的保護(hù)是中斷技術(shù)中一個(gè)很重要的環(huán)節(jié)。在進(jìn)入中斷服務(wù)程序期間,只有返回地址,即程序計(jì)數(shù)器PC的值被自動(dòng)壓入堆棧。若需要保留其他寄存器的內(nèi)容,就得由程序員另想辦法。由于PIC單片機(jī)的指令系統(tǒng)中沒(méi)有像其他單片機(jī)那樣的PUSH(入棧)和POP(出棧)之類的指令,所以要用1段用戶程序來(lái)實(shí)現(xiàn)類似的功能。因?yàn)槭怯?段程序來(lái)實(shí)現(xiàn)現(xiàn)場(chǎng)保護(hù),而程序的執(zhí)行有可能會(huì)影響到W寄存器和STATUS寄存器,所以,首先應(yīng)該把這2個(gè)寄存器保護(hù)起來(lái),然后再去保存其他用戶認(rèn)為有必要保護(hù)的寄存器。并且在PIC單片機(jī)中,中斷現(xiàn)場(chǎng)數(shù)據(jù)不是保留到芯片的堆棧存儲(chǔ)區(qū)中,而是保留在用戶自己選擇的一些文件寄存器(即RAM數(shù)據(jù)存儲(chǔ)器單元)中,當(dāng)然一般應(yīng)該選擇通用寄存器來(lái)保護(hù)現(xiàn)場(chǎng)。下面給出的是1段原廠家最新提供的實(shí)現(xiàn)保護(hù)中斷現(xiàn)場(chǎng)的范例程序片段。
 ??;將W、STATUS和PCLATH寄存器的內(nèi)容保存到臨時(shí)備份寄存器中
 ?。?]MOVWFW_TEMP   ;復(fù)制W到它的臨時(shí)備份寄存器W_TEMP中
 ?。?]SWAPFSTATUS,W ;將STATUS寄存器高低半字節(jié)交換后放入W
  [3]CLRFSTATUS ;不管當(dāng)前處在哪個(gè)體,都設(shè)置體0作當(dāng)前體
 ?。?]MOVWFSTATUS_TEMP ;保存STATUS到體0上的臨時(shí)寄存器STATUS_TEMP
  [5]MOVF PCLATH, W ;把寄存器PCLATH內(nèi)容復(fù)制到W中
 ?。?]MOVWFPCLATH_TEMP ;經(jīng)W將PCLATH內(nèi)容轉(zhuǎn)到臨時(shí)寄存器PCLATH_TEMP
 ?。?]CLRFPCLATH ;不管當(dāng)前處在哪頁(yè),都把PCLATH設(shè)置成指向頁(yè)0(中斷服務(wù)程序的核心部分)
  [8]MOVFPCLATH_TEMP, W ;經(jīng)過(guò)W轉(zhuǎn)移
  [9]MOVWFPCLATH ;恢復(fù)PCLATH內(nèi)容
  [10]SWAPFSTATUS_TEMP,W ;將STATUS_TEMP寄存器高低半字節(jié)交換后放入W 

[11]MOVWFSTATUS ;把W內(nèi)容移動(dòng)到STATUS寄存器,(同時(shí)也把當(dāng)前體恢復(fù)到原先的體上)
  [12]SWAPFW_TEMP,F ;將W_TEMP內(nèi)容高低半字節(jié)交換后放回
  [13]SWAPFW_TEMP,W ;再次將W_TEMP內(nèi)容高低半字節(jié)交換后放入W
  這段程序適用于PIC16CXX系列中各款型號(hào)的單片機(jī)。在這段例程之前,假設(shè)預(yù)先對(duì)于待保留的各個(gè)寄存器都分別定義了相應(yīng)的臨時(shí)備份寄存器。用后綴“_TEMP”表示臨時(shí)備份寄存器,例如“W”的臨時(shí)備份寄存器記為“W_TEMP”。對(duì)于這些臨時(shí)備份寄存器究竟需要定義多少個(gè),定義在通用寄存器區(qū)域中的哪個(gè)位置,都是值得考究的問(wèn)題。并且單片機(jī)的型號(hào)不同,其內(nèi)部的通用寄存器區(qū)域的分布也不同,因此這就使得臨時(shí)備份寄存器定義的數(shù)量和位置也不能相同。
  例如,對(duì)于PIC16F873/874來(lái)說(shuō),要求寄存器W_TEMP必須在文件寄存器(即RAM數(shù)據(jù)存儲(chǔ)器)的體0和體1上各定義1個(gè),并且這2個(gè)W_TEMP寄存器單元必須具有相同的體內(nèi)地址碼(比如,在體0上把W_TEMP定義在20H單元,則在體1上就把另一個(gè)W_TEMP定義在A0H單元);而其他寄存器的臨時(shí)備份寄存器(如STATUS_TEMP和PCLATH_TEMP)都僅僅需要在體0上定義1個(gè)即可。 

又例如,對(duì)于PIC16F87X子系列中的其他5款型號(hào)來(lái)說(shuō),情況有所不同。其文件寄存器各個(gè)體的頂端部分有16個(gè)地址空間,都會(huì)尋址到相同的16個(gè)物理單元上。這16個(gè)單元不需要體選尋址,或者說(shuō),尋址這16個(gè)單元與體選碼無(wú)關(guān),即與當(dāng)前所處的體無(wú)關(guān)。因此,將各個(gè)臨時(shí)備份寄存器都安排在這個(gè)位置(W_TEMP也只需要定義1個(gè)即可)最為合適。這樣做可以使得現(xiàn)場(chǎng)保護(hù)和現(xiàn)場(chǎng)恢復(fù)變得非常容易。中斷是一種隨機(jī)發(fā)生的事件。進(jìn)入中斷服務(wù)程序后,第1個(gè)要保存的應(yīng)該是工作寄存器W。原因是PIC單片機(jī)沒(méi)有在“不同寄存器”之間進(jìn)行直接傳遞的指令,這樣的功能得用W作中轉(zhuǎn)(需要2條指令)才能實(shí)現(xiàn),所以應(yīng)該先把W寄存器騰空(對(duì)應(yīng)程序中第1條指令)。急于騰空W寄存器,又不能破壞當(dāng)前狀態(tài)寄存器STATUS中的體選碼,還不能影響當(dāng)前狀態(tài)寄存器STATUS內(nèi)的標(biāo)志位,可又無(wú)法確定主程序所處的RAM數(shù)據(jù)存儲(chǔ)器當(dāng)前體是哪一個(gè),就只好在主程序所有可能選擇到的每一個(gè)RAM數(shù)據(jù)存儲(chǔ)器體上的相同位置,都定義1個(gè)W_TEMP臨時(shí)備份寄存器。
  一旦把工作寄存器W騰空后,緊接著就應(yīng)將狀態(tài)寄存器STATUS的內(nèi)容轉(zhuǎn)移到W中。完成這一操作的指令也不能影響到STATUS寄存器內(nèi)部原有的標(biāo)志位,原因是STATUS寄存器的內(nèi)容在此之前還沒(méi)有安全地保護(hù)起來(lái)。經(jīng)過(guò)仔細(xì)分析得知,PIC16系列單片機(jī)的指令系統(tǒng)中有3條“MOV”傳送指令。但是,只有1條“MOVF f,W”是以RAM單元為源寄存器,以W為目標(biāo)寄存器的;而這條指令的操作過(guò)程又偏偏會(huì)影響“Z”標(biāo)志位。因此,該指令就不能使用了,只好用1條既有高、低半字節(jié)交換功能又有傳遞功能的“SWAPFSTATUS,W”來(lái)勉強(qiáng)頂替(對(duì)應(yīng)程序中第2條指令)。不過(guò)在此只利用它的傳遞功能,其交換功能帶來(lái)的多余操作還得記下來(lái),等到工作完成之后還得把它倒換回來(lái)。
STATUS寄存器的內(nèi)容已經(jīng)保存到W中時(shí),就可以大膽地將其清0了,以便把定義著STATUS_TEMP和PCLATH_TEMP的體0設(shè)置為當(dāng)前體(對(duì)應(yīng)程序中第3條指令)。經(jīng)過(guò)以上幾步特別需要謹(jǐn)慎的操作過(guò)后,就可以輕而易舉地將寄存器STATUS和PCLATH的內(nèi)容保存到各自的臨時(shí)備份寄存器中了(對(duì)應(yīng)程序中第4~6條指令)。 

在單片機(jī)初始加電時(shí),自動(dòng)將PCLATH清0,以避免其內(nèi)容出現(xiàn)隨機(jī)值,也就是為了避免在以后的程序運(yùn)行過(guò)程中CPU發(fā)生不可預(yù)料的跳轉(zhuǎn),而造成程序的“跑飛”。由此可見(jiàn),寄存器PCLATH對(duì)于程序的安全運(yùn)行是至關(guān)重要的,不可輕視。程序一旦進(jìn)入服務(wù)程序后,PCLATH的當(dāng)前值為何就無(wú)從考證,實(shí)際上就失去了對(duì)于PCLATH內(nèi)容的知情權(quán)。只好像單片機(jī)初始上電那樣將其清0,重新把它強(qiáng)行“拉入”知情范圍(對(duì)應(yīng)程序中第7條指令)。
  PCLATH的內(nèi)容在2種情況下會(huì)影響到程序的走向:第1種情況是當(dāng)執(zhí)行GOTO和CALL這2條跳轉(zhuǎn)指令時(shí),11位地址碼來(lái)源于指令碼中,決定程序存儲(chǔ)器頁(yè)面的(PC值的)最高2位,來(lái)源于PCLATH<4:3>,即這種情況下只有PCLATH的2位影響程序走向。單單就這一種情況而言,只要用戶程序不超過(guò)第0頁(yè)(或稱頁(yè)0)的2KB范圍,對(duì)于程序員來(lái)說(shuō),PC值的最高2位可以忽略,因而PCLATH寄存器PCLATH<4:3>的2位也可以忽略。第2種情況是,以PCL為目標(biāo)的算術(shù)運(yùn)算、邏輯運(yùn)算或傳送操作指令(PIC16系列單片機(jī)的指令系統(tǒng)中具備14條這樣的指令),在操作過(guò)程中,自動(dòng)用PCLATH寄存器的低5位裝載PC的高5位PC<12:8>,影響程序走向的PCLATH內(nèi)容就多達(dá)5位。即使對(duì)于用戶程序不超過(guò)(第0頁(yè)范圍內(nèi)的)2KB的情況,也至少會(huì)有3位影響到程序的走向。對(duì)于程序員來(lái)說(shuō),PCLATH的內(nèi)容就不可忽略,必須保護(hù)。 

總而言之,對(duì)于寄存器PCLATH的保護(hù)和處理(對(duì)應(yīng)程序中陰影標(biāo)出的部分指令,即第5~9條)并不是什么情況下都是必需的,但是在編寫中斷服務(wù)程序時(shí),統(tǒng)一安排這些指令也沒(méi)有任何壞處。只要主程序和中斷服務(wù)程序中都不需要修改PCLATH寄存器的內(nèi)容,就可以不保護(hù)它。具體地說(shuō),只有當(dāng)同時(shí)滿足以下2個(gè)條件時(shí),陰影標(biāo)出的部分指令(即第5~9條)才可以省略。
 ?。?)在主程序和中斷服務(wù)程序中不都存在跨頁(yè)跳轉(zhuǎn)。例如:用戶程序沒(méi)有使用第0頁(yè)2KB空間之外的程序存儲(chǔ)器,或者用戶程序雖然超出了2KB的范圍,但是,在主程序和中斷服務(wù)程序中沒(méi)有同時(shí)用到GOTO或CALL指令,都能滿足該條。
  (2) 在主程序和中斷服務(wù)程序中沒(méi)有同時(shí)使用以PCL為目標(biāo)的操作指令(比如查表)。
保護(hù)現(xiàn)場(chǎng)的操作次序與恢復(fù)現(xiàn)場(chǎng)的操作次序應(yīng)該相反。程序中的第8~11條就是按照相反的順序恢復(fù)寄存器PCLATH和 STATUS內(nèi)容的。但是,不要忘記保護(hù)現(xiàn)場(chǎng)時(shí)采用“SWAPF STATUS,W”指令產(chǎn)生的多余的交換操作,在此只好再采用同樣的方法將其交換回來(lái)(對(duì)應(yīng)程序中第10條指令)。最后2條指令,將W_TEMP內(nèi)容的高、低半字節(jié)交換了2遍,才被恢復(fù)到工作寄存器W中。如果只用1條傳送指令“MOVF W_TEMP,W”又會(huì)產(chǎn)生1個(gè)新的問(wèn)題:“MOVF W_TEMP,W”指令會(huì)影響“Z”標(biāo)志位,會(huì)破壞此前已經(jīng)被恢復(fù)的寄存器STATUS的內(nèi)容,這是我們所不希望的,也是不能容忍的。因此,在程序中利用了2條不影響標(biāo)志位的SWAP指令(即第12,13兩條指令)。雖然麻煩一點(diǎn),但可以使這個(gè)問(wèn)題得到圓滿的解決。 

最后必須進(jìn)一步強(qiáng)調(diào)的是,并不是所有情況下編寫的中斷服務(wù)程序中都需要現(xiàn)場(chǎng)保護(hù),或者都需要像以上范例程序那樣進(jìn)行現(xiàn)場(chǎng)保護(hù)。有些情況下僅僅保護(hù)W、STATUS和PCLATH這3個(gè)寄存器還不夠。不過(guò)在此程序片段的基礎(chǔ)上,再增加或者減少需要保護(hù)的寄存器的個(gè)數(shù)都是輕而易舉的事。不要忘記,在保護(hù)任何文件寄存器之前都必須先把工作寄存器W保護(hù)起來(lái)才行得通。
  3 需要注意的幾個(gè)問(wèn)題
 ?。?)中斷標(biāo)志位的狀態(tài)與該中斷源是否產(chǎn)生中斷無(wú)關(guān)。換句話說(shuō),不管是否允許其中斷,只要滿足中斷的條件,中斷標(biāo)志位就會(huì)被置位。另外,也可以利用軟件將中斷標(biāo)志位置“1”或清“0”。
 ?。?)當(dāng)開(kāi)放某一中斷源時(shí),該中斷源就是通過(guò)中斷標(biāo)志位向CPU申請(qǐng)中斷的。無(wú)論什么原因,只要將中斷標(biāo)志位置位,就會(huì)產(chǎn)生中斷。如果用軟件強(qiáng)行將中斷標(biāo)志位置位,也會(huì)產(chǎn)生中斷。
 ?。?)如果在中斷被屏蔽(或禁止)的情況下,中斷標(biāo)志位被置位,只要不被清除就會(huì)一直潛伏下來(lái),那么,一旦解除屏蔽,就會(huì)立即產(chǎn)生中斷。
 ?。?)如果在中斷被禁止的情況下,中斷標(biāo)志位已經(jīng)被置位,但是,假如在允許其中斷之前將它清除,那么,即使解除禁止,它也不會(huì)產(chǎn)生中斷。
 ?。?)當(dāng)CPU相應(yīng)的任何一個(gè)中斷時(shí),全局中斷屏蔽位GIE將會(huì)自動(dòng)清0;當(dāng)中斷返回時(shí)它又會(huì)自動(dòng)恢復(fù)為1。如果在中斷處理期間用軟件將已經(jīng)復(fù)位的GIE重新置位,這時(shí)再出現(xiàn)中斷請(qǐng)求,就可以形成中斷嵌套。也就是說(shuō),如果在響應(yīng)某一中斷期間又響應(yīng)了其他中斷請(qǐng)求,就形成了中斷嵌套。發(fā)生中斷嵌套時(shí),前一中斷處理過(guò)程被暫停而進(jìn)入后一中斷處理,當(dāng)后一中斷過(guò)程被處理完畢之后,才會(huì)繼續(xù)處理前一中斷。照此方式,還可以形成多級(jí)嵌套,甚至自身嵌套。不過(guò)嵌套的級(jí)數(shù)絕對(duì)不能超過(guò)硬件堆棧的深度。 

(6) 對(duì)于中斷響應(yīng)和處理時(shí)間有嚴(yán)格要求的應(yīng)用,保護(hù)現(xiàn)場(chǎng)的指令安排也應(yīng)考慮延時(shí)問(wèn)題。
 ?。?)如果同時(shí)發(fā)生多個(gè)中斷請(qǐng)求,得到優(yōu)先處理的中斷完全取決于在中斷服務(wù)程序中檢查中斷源的順序。原因是各個(gè)中斷源之間不存在優(yōu)先級(jí)別之分。
如果清除中斷標(biāo)志位的指令安排在中斷服務(wù)程序的尾部,就有可能丟失響應(yīng)在處理中斷期間該中斷源第2次中斷請(qǐng)求的機(jī)會(huì)。


联系我们: 沙河市| 安远县| 肃宁县| 察哈| 宣威市| 汤原县| 资阳市| 扎囊县| 宁德市| 子长县| 桦甸市| 平谷区| 班玛县| 和林格尔县| 金堂县| 青铜峡市| 礼泉县| 昔阳县| 通辽市| 叙永县| 临夏市| 广水市| 广元市| 石棉县| 当阳市| 赫章县| 宁化县| 邢台县| 珠海市| 云和县| 敦化市| 宁明县| 分宜县| 江口县| 德化县| 祁连县| 应用必备| 玛曲县| 晋中市| 富平县| 康保县|