<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > PIC16F87X單片機(jī)中斷系統(tǒng)應(yīng)用須關(guān)注的問(wèn)題

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

          作者: 時(shí)間:2012-04-10 來(lái)源:網(wǎng)絡(luò) 收藏

          在圖2中,第1行是時(shí)鐘脈沖信號(hào),每4個(gè)時(shí)鐘周期對(duì)應(yīng)1個(gè)指令周期。第2行就是指令周期信號(hào)。該信號(hào)只有在RC 振蕩模式下,從OSC2腳上可以向片外送出。第3行是外部引腳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,見圖2中第6行。同時(shí)在該指令周期內(nèi)完成到中斷服務(wù)程序的跳轉(zhuǎn),并且實(shí)現(xiàn)提取該子程序的首條指令,即指令(0004H),見圖2中第7行。在其后的1個(gè)指令周期內(nèi),正式開始執(zhí)行中斷服務(wù)程序的第1條指令,見圖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系列(低檔產(chǎn)品PIC16C5X和PIC12C5X系列不具備中斷功能),采用的是“多源中斷”的設(shè)計(jì)方案(即1個(gè)中斷向量對(duì)應(yīng)著多個(gè)中斷源),只有惟一的1個(gè)中斷向量,或者說(shuō)只有1個(gè)中斷服務(wù)程序入口地址。這就意味著,此類的中斷服務(wù)程序只能編寫1個(gè)。這類單片機(jī)的硬件結(jié)構(gòu)得到了簡(jiǎn)化,那么,相應(yīng)的軟件設(shè)計(jì)上就得多開銷一些。在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ì)隨著被開放的中斷源的個(gè)數(shù)的增加而增加。最好情況是只有1個(gè)中斷源被開放,這時(shí)不需要檢測(cè)中斷源就可以立即進(jìn)入針對(duì)性處理;最壞情況是所有中斷源全部開放,此時(shí)用在檢測(cè)中斷源上的時(shí)間會(huì)最長(zhǎng)。

          另外,PIC單片機(jī)中采用的是硬件堆棧結(jié)構(gòu)。其好處是既不占用程序存儲(chǔ)器空間,也不占用數(shù)據(jù)存儲(chǔ)器空間,同時(shí)也不需用戶去操作堆棧指針;但此時(shí)也帶來(lái)1個(gè)不可回避的弱點(diǎn),即不具備像其他單片機(jī)指令中的壓棧(PUSH)和出棧(POP)指令那樣,實(shí)現(xiàn)中斷現(xiàn)場(chǎng)的保護(hù)會(huì)麻煩一些,并且占用的處理時(shí)間也相應(yīng)多一點(diǎn)。

          2 中斷的現(xiàn)場(chǎng)保護(hù)

          中斷現(xiàn)場(chǎng)的保護(hù)是中斷技術(shù)中一個(gè)很重要的環(huán)節(jié)。在進(jìn)入中斷服務(wù)程序期間,只有返回地址,即程序計(jì)數(shù)器PC的值被自動(dòng)壓入堆棧。若需要保留其他寄存器的內(nèi)容,就得由程序員另想辦法。由于PIC單片機(jī)的指令中沒(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
           ?。?]CLRFSTATUS ;不管當(dāng)前處在哪個(gè)體,都設(shè)置體0作當(dāng)前體
           ?。?]MOVWFSTATUS_TEMP ;保存STATUS到體0上的臨時(shí)寄存器STATUS_TEMP
           ?。?]MOVF PCLATH, W ;把寄存器PCLATH內(nèi)容復(fù)制到W中
            [6]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)移
           ?。?]MOVWFPCLATH ;恢復(fù)PCLATH內(nèi)容
           ?。?0]SWAPFSTATUS_TEMP,W ;將STATUS_TEMP寄存器高低半字節(jié)交換后放入W
           ?。?1]MOVWFSTATUS ;把W內(nèi)容移動(dòng)到STATUS寄存器,(同時(shí)也把當(dāng)前體恢復(fù)到原先的體上)
            [12]SWAPFW_TEMP,F ;將W_TEMP內(nèi)容高低半字節(jié)交換后放回
           ?。?3]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è)位置,都是值得考究的。并且單片機(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ì)于子系列中的其他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條指令)。



          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();