中斷。PIC單片機(jī)中采用的是硬件堆棧結(jié)構(gòu),不占用程序存儲器空間,也不占用數(shù)據(jù)存儲器空間,同時也無需用戶去操作堆棧指針;但同時也就決定了它不具備其他單片機(jī)指令系統(tǒng)中的壓棧(PUSH)和出棧(POP)指令。實現(xiàn)中斷現(xiàn)場保護(hù)時,不能用堆棧來實現(xiàn),而是通過變量的復(fù)制備份來實現(xiàn)。一般的實現(xiàn)辦法是:先確定要保護(hù)的現(xiàn)場,一般包括WReg、STATUS等寄存器的內(nèi)容,然后在各個頁都定義與這些寄存器對應(yīng)的變量,以備份現(xiàn)場。發(fā)生中斷時,在中斷處理代碼開始處先將這些現(xiàn)場寄存器內(nèi)容復(fù)制到備份變量,退出中斷處理時再復(fù)制回去恢復(fù)現(xiàn)場:
ORG 0x004 ;中斷向量人口
movwf w_temp ;保存當(dāng)前w 寄存器內(nèi)容
mov STATUS,w ;將STATUS 寄存器內(nèi)容復(fù)制到w
movwf status_temp ;保存STATUS寄存器內(nèi)容
movf PCLATH,w ;將PCLATH寄存器復(fù)制到w
movw{ pclath_temp ;保存PCLATH 器內(nèi)容
……
;中斷處理代碼放在這里
……
movf pclath_temp,w;
movwf PCLATH ;恢復(fù)PCLATH 寄存器內(nèi)容
movf status_temp,w;
movwf STATUS ;恢復(fù)STATUS寄存器內(nèi)容
swapf w_temp,f
swapf w_temp,w ;恢復(fù)w 寄存器內(nèi)容
retfie ;中斷返回
因為中斷發(fā)生具有隨機(jī)性,發(fā)生中斷時當(dāng)前的頁是哪個也具有不確定性,所以只在某個頁(如BANK0)中定義一套備份變量w_temp、status_temp等,處理起來是很麻煩的,也要耗費CPU 處理時間,所以一般在每個頁BANK都定義了一套用于備份現(xiàn)場的變量。這顯然是浪費空間的辦法。
進(jìn)行數(shù)據(jù)存儲器的變量規(guī)劃后,程序的執(zhí)行過程都是在BANK0,因此在BANK0定義一套備份變量就可以了。要備份的現(xiàn)場包含哪些寄存器,可以根據(jù)系統(tǒng)具體情況而定。
基于上面設(shè)計的中斷處理程序,總是默認(rèn)當(dāng)前的頁是BANK0。如果在訪問一些不在BANK0的特殊寄存器而沒有關(guān)閉中斷,而剛好此時發(fā)生中斷,則此時不能正確訪問到wREG_TEMP等備份變量了,這種情況就是個錯誤。
結(jié)語
用PIC16F87x單片機(jī)開發(fā)室內(nèi)監(jiān)控系統(tǒng),進(jìn)行變量的規(guī)劃,免去大量的頁選擇問題帶來的不便,能夠避免分頁沒處理好而帶來程序BUG。PIC系列單片機(jī)都有類似的硬件結(jié)構(gòu)和指令系統(tǒng),所以存儲器的規(guī)劃對于其他PIC系列單片機(jī)應(yīng)該也是起作用的。另外,這也從另一個角度說明,在設(shè)計階段對系統(tǒng)變量的物理存儲進(jìn)行適當(dāng)?shù)囊?guī)劃,有時會得到意想不到的效果。





