PIC16F87X單片機中斷系統應用須關(guān)注的問(wèn)題
在圖2中,第1行是系統時(shí)鐘脈沖信號,每4個(gè)時(shí)鐘周期對應1個(gè)指令周期。第2行就是指令周期信號。該信號只有在RC 振蕩模式下,從OSC2腳上可以向片外送出。第3行是單片機外部引腳INT送入的中斷脈沖信號。外部中斷信號INT是用邊沿觸發(fā)的。假設預先設定的是 INT中斷信號上升沿有效的話(huà),則該信號的上升沿將會(huì )在1個(gè)時(shí)鐘周期后引發(fā)中斷標志位INTF被置位。第4行代表INTF信號。每個(gè)指令周期內的第2個(gè)時(shí)鐘脈沖上升沿時(shí),該信號被抽檢1次。一旦檢測到INTF信號被設置為“1”,則CPU會(huì )在接下來(lái)的1個(gè)指令周期內,將全局中斷屏蔽位GIE清零。第5行是全局中斷屏蔽位GIE。在GIE信號被清零的下一個(gè)指令周期內,程序計數器PC被置入中斷向量0004H,見(jiàn)圖2中第6行。同時(shí)在該指令周期內完成到中斷服務(wù)程序的跳轉,并且實(shí)現提取該子程序的首條指令,即指令(0004H),見(jiàn)圖2中第7行。在其后的1個(gè)指令周期內,正式開(kāi)始執行中斷服務(wù)程序的第1條指令,見(jiàn)圖2中第8行。自INT引腳輸入有效信號,到中斷服務(wù)程序的第1條指令得到執行,大約需要3~4個(gè)指令周期的延時(shí)。更精確的延遲時(shí)間取決于中斷事件的發(fā)生時(shí)機。
以上描述的只是1次中斷從申請到得到CPU的響應的延遲時(shí)間。下面分析從CPU響應1次中斷到該中斷得到有效處理的延遲時(shí)間。由于具有中斷功能的PIC系列單片機(低檔產(chǎn)品PIC16C5X和PIC12C5X系列不具備中斷功能),采用的是“多源中斷”的設計方案(即1個(gè)中斷向量對應著(zhù)多個(gè)中斷源),只有惟一的1個(gè)中斷向量,或者說(shuō)只有1個(gè)中斷服務(wù)程序入口地址。這就意味著(zhù),此類(lèi)單片機的中斷服務(wù)程序只能編寫(xiě)1個(gè)。這類(lèi)單片機的硬件結構得到了簡(jiǎn)化,那么,相應的軟件設計上就得多開(kāi)銷(xiāo)一些。在1個(gè)中斷服務(wù)程序中,若想對多個(gè)中斷源作出處理,就必須在進(jìn)入中斷服務(wù)程序后,首先執行調查具體中斷源的一條或多條指令,其后才能對查到的中斷源作出有針對性的服務(wù)。如此以來(lái),就形成了1次中斷從CPU響應到進(jìn)入針對性處理的延遲時(shí)間。該時(shí)間有長(cháng)有短,它會(huì )隨著(zhù)被開(kāi)放的中斷源的個(gè)數的增加而增加。最好情況是只有1個(gè)中斷源被開(kāi)放,這時(shí)不需要檢測中斷源就可以立即進(jìn)入針對性處理;最壞情況是所有中斷源全部開(kāi)放,此時(shí)用在檢測中斷源上的時(shí)間會(huì )最長(cháng)。
另外,PIC單片機中采用的是硬件堆棧結構。其好處是既不占用程序存儲器空間,也不占用數據存儲器空間,同時(shí)也不需用戶(hù)去操作堆棧指針;但此時(shí)也帶來(lái)1個(gè)不可回避的弱點(diǎn),即不具備像其他單片機指令系統中的壓棧(PUSH)和出棧(POP)指令那樣,實(shí)現中斷現場(chǎng)的保護會(huì )麻煩一些,并且占用的處理時(shí)間也相應多一點(diǎn)。
2 中斷的現場(chǎng)保護問(wèn)題
中斷現場(chǎng)的保護是中斷技術(shù)中一個(gè)很重要的環(huán)節。在進(jìn)入中斷服務(wù)程序期間,只有返回地址,即程序計數器PC的值被自動(dòng)壓入堆棧。若需要保留其他寄存器的內容,就得由程序員另想辦法。由于PIC單片機的指令系統中沒(méi)有像其他單片機那樣的PUSH(入棧)和POP(出棧)之類(lèi)的指令,所以要用1段用戶(hù)程序來(lái)實(shí)現類(lèi)似的功能。因為是用1段程序來(lái)實(shí)現現場(chǎng)保護,而程序的執行有可能會(huì )影響到W寄存器和STATUS寄存器,所以,首先應該把這2個(gè)寄存器保護起來(lái),然后再去保存其他用戶(hù)認為有必要保護的寄存器。并且在PIC單片機中,中斷現場(chǎng)數據不是保留到芯片的堆棧存儲區中,而是保留在用戶(hù)自己選擇的一些文件寄存器(即RAM數據存儲器單元)中,當然一般應該選擇通用寄存器來(lái)保護現場(chǎng)。下面給出的是1段原廠(chǎng)家最新提供的實(shí)現保護中斷現場(chǎng)的范例程序片段。
??;將W、STATUS和PCLATH寄存器的內容保存到臨時(shí)備份寄存器中
?。?]MOVWFW_TEMP ;復制W到它的臨時(shí)備份寄存器W_TEMP中
?。?]SWAPFSTATUS,W ;將STATUS寄存器高低半字節交換后放入W
?。?]CLRFSTATUS ;不管當前處在哪個(gè)體,都設置體0作當前體
?。?]MOVWFSTATUS_TEMP ;保存STATUS到體0上的臨時(shí)寄存器STATUS_TEMP
?。?]MOVF PCLATH, W ;把寄存器PCLATH內容復制到W中
?。?]MOVWFPCLATH_TEMP ;經(jīng)W將PCLATH內容轉到臨時(shí)寄存器PCLATH_TEMP
?。?]CLRFPCLATH ;不管當前處在哪頁(yè),都把PCLATH設置成指向頁(yè)0 (中斷服務(wù)程序的核心部分)
?。?]MOVFPCLATH_TEMP, W ;經(jīng)過(guò)W轉移
?。?]MOVWFPCLATH ;恢復PCLATH內容
?。?0]SWAPFSTATUS_TEMP,W ;將STATUS_TEMP寄存器高低半字節交換后放入W
?。?1]MOVWFSTATUS ;把W內容移動(dòng)到STATUS寄存器,(同時(shí)也把當前體恢復到原先的體上)
?。?2]SWAPFW_TEMP,F ;將W_TEMP內容高低半字節交換后放回
?。?3]SWAPFW_TEMP,W ;再次將W_TEMP內容高低半字節交換后放入W
這段程序適用于PIC16CXX系列中各款型號的單片機。在這段例程之前,假設預先對于待保留的各個(gè)寄存器都分別定義了相應的臨時(shí)備份寄存器。用后綴 “_TEMP”表示臨時(shí)備份寄存器,例如“W”的臨時(shí)備份寄存器記為“W_TEMP”。對于這些臨時(shí)備份寄存器究竟需要定義多少個(gè),定義在通用寄存器區域中的哪個(gè)位置,都是值得考究的問(wèn)題。并且單片機的型號不同,其內部的通用寄存器區域的分布也不同,因此這就使得臨時(shí)備份寄存器定義的數量和位置也不能相同。
例如,對于PIC16F873/874來(lái)說(shuō),要求寄存器W_TEMP必須在文件寄存器(即RAM數據存儲器)的體0和體1上各定義1 個(gè),并且這2個(gè)W_TEMP寄存器單元必須具有相同的體內地址碼(比如,在體0上把W_TEMP定義在20H單元,則在體1上就把另一個(gè)W_TEMP定義在A(yíng)0H單元);而其他寄存器的臨時(shí)備份寄存器(如STATUS_TEMP和PCLATH_TEMP)都僅僅需要在體0上定義1個(gè)即可。
又例如,對于PIC16F87X子系列中的其他5款型號來(lái)說(shuō),情況有所不同。其文件寄存器各個(gè)體的頂端部分有16個(gè)地址空間,都會(huì )尋址到相同的16個(gè)物理單元上。這16個(gè)單元不需要體選尋址,或者說(shuō),尋址這16個(gè)單元與體選碼無(wú)關(guān),即與當前所處的體無(wú)關(guān)。因此,將各個(gè)臨時(shí)備份寄存器都安排在這個(gè)位置(W_TEMP也只需要定義1個(gè)即可)最為合適。這樣做可以使得現場(chǎng)保護和現場(chǎng)恢復變得非常容易。中斷是一種隨機發(fā)生的事件。進(jìn)入中斷服務(wù)程序后,第1個(gè)要保存的應該是工作寄存器W。原因是PIC單片機沒(méi)有在“不同寄存器”之間進(jìn)行直接傳遞的指令,這樣的功能得用W作中轉(需要2條指令)才能實(shí)現,所以應該先把W寄存器騰空(對應程序中第1條指令)。急于騰空W寄存器,又不能破壞當前狀態(tài)寄存器 STATUS中的體選碼,還不能影響當前狀態(tài)寄存器STATUS內的標志位,可又無(wú)法確定主程序所處的RAM數據存儲器當前體是哪一個(gè),就只好在主程序所有可能選擇到的每一個(gè)RAM數據存儲器體上的相同位置,都定義1個(gè)W_TEMP臨時(shí)備份寄存器。
一旦把工作寄存器W騰空后,緊接著(zhù)就應將狀態(tài)寄存器STATUS的內容轉移到W中。完成這一操作的指令也不能影響到STATUS寄存器內部原有的標志位,原因是STATUS寄存器的內容在此之前還沒(méi)有安全地保護起來(lái)。經(jīng)過(guò)仔細分析得知,PIC16系列單片機的指令系統中有3條“MOV”傳送指令。但是,只有1條“MOVF f,W”是以RAM單元為源寄存器,以W為目標寄存器的;而這條指令的操作過(guò)程又偏偏會(huì )影響“Z”標志位。因此,該指令就不能使用了,只好用1條既有高、低半字節交換功能又有傳遞功能的“SWAPFSTATUS,W”來(lái)勉強頂替(對應程序中第2條指令)。不過(guò)在此只利用它的傳遞功能,其交換功能帶來(lái)的多余操作還得記下來(lái),等到工作完成之后還得把它倒換回來(lái)。
STATUS寄存器的內容已經(jīng)保存到W中時(shí),就可以大膽地將其清0了,以便把定義著(zhù) STATUS_TEMP和PCLATH_TEMP的體0設置為當前體(對應程序中第3條指令)。經(jīng)過(guò)以上幾步特別需要謹慎的操作過(guò)后,就可以輕而易舉地將寄存器STATUS和PCLATH的內容保存到各自的臨時(shí)備份寄存器中了(對應程序中第4~6條指令)。
評論