PIC16C5X內部有384~2K的只讀程序存貯器,下面論述其結構和堆棧。
§1.4.1 程序存儲器結構
PIC16C5X程序存儲器結構如圖1.3所示:
從上圖可看出,PIC程序存儲器采用分頁結構,每頁長0.5K。因此對于PIC16C52程序存儲器在1頁之內,而對于PIC16C54和PIC15C55程序存儲器容量為1頁,PIC16C56和PIC16C57 的容量則分別為2頁和4頁。頁面地址由狀態(tài)寄存器f3的第5位和第6位(PA0、PA1)確定。程序轉移時,在本頁內可直接進行;在需跨頁跳轉時(GOTO、CALL指令),則必須根據將要跳轉去的頁面,把f3中的PA0、PA1位置成相應的值。具體請參考f3寄存器描述及§2.7.2 程序設計基礎的程序技巧例子。
§1.4.2 堆棧
PIC16C5X設有二層堆棧,堆棧1和堆棧2,供子程序調用。涉及堆棧操作的指令有二條。
1、CALL--在主程序中第一次執(zhí)行CALL指令時,將PC值加1后推入堆棧1,堆棧1 原有的內容則被推入堆棧2中。這時子程序中還可再做一次子程序嵌套,即再執(zhí)行一次 CALL指令。如果子程序調用多于二層時,堆棧中只存放最近的二個返回地址。
當執(zhí)行一條CALL指令時,狀態(tài)寄存器f3中的將頁面尋址位PA1、PA0將被置入到PC的最高二位(第11位和第10位),而PC的第9位總是被置為0,如圖1.3所示。所以這時PC 值將是
這意味著在PIC16C5X中,子程序起始地址只能放在每個程序存儲頁面的上半頁,即低地址的那一半(000-0FF、200-2FF、400-4FF、600-6FF)。注意,這里指的是子程序的起始地址,即子程序頭。而子程序體是可以延伸到下半頁去的。
對于PIC16C56和PIC16C57,由于程序空間分別為1K和2K,可能存在跨頁面子程序調用。所以調用子程序前必須先把f3中的PA0、PA1設置成該子程序所在的頁面地址。返回后再將其恢復成當前的頁面值。當然如果這時子程序是在同一頁面,則可省去這一過程。
2、RETLW--該指令把棧頂(堆棧1)的值寫入PC,同時還把堆棧2的值拷貝到堆棧1 去。子程序總是返回到調用它時所在的地方,不管它是處在什么頁面,也不管f3寄存器中的PA0、PA1這時是指在什么頁面。但是執(zhí)行RETLW(子程序返回)指令并不會改變f3中PA0、PA1的值,所以當你從一次跨頁面的子程序調用返回時,不要忘了恢復f3中的原先的PA0和PA1值。請參考上面關于CALL指令的敘述。
由于堆棧和PC的寬度是相同的,所以你可以在程序的任何地方執(zhí)行一條CALL 指令來調用子程序。但是對于跨頁面的調用,你要小心處理f3中的頁面地址位PA0和PA1,請參考第二章指令詳解中的CALL實例。





