靈活使用PIC16C57单片机的PROGRAM MEMORY

发布者:快乐行者最新更新时间:2011-02-24 手机看文章 扫描二维码
随时随地手机看文章

      當您使用Microchip公司的PIC16C57单片机在設計程式時,是否被它的PROGRAM MEMORY需分PAGE使用,而PAGE之設定又影響到goto、call、addwf 2、movwf 2四個指令之執行結果而困擾不已呢?以下是小弟領悟出來的一點心得,在此野人獻曝,與大家分享。
    PIC16C57单片机之PROGRAM MEMORY共有2 K words,分為四個PAGE,每個PAGE有512個words;goto、call、addwf 2、movwf 2四個指令之執行,會改變PROGRAM COUNTER內容,其結果也受STATUS WORD REGISTER f3之bit 6, 5的影響,如圖(一)所示;改變STATUS WORD REGISTER之bit 6, 5以下一律以"PAGE(的)控制"稱呼。
    除此之外,每個PAGE分為前半部及後半部,call、addwf 2、movwf 2三個指令執行結果只會跳到某一PAGE內的前半部,因為這三個指令執行後會使PROGRAM COUNTER的bit 8變為0,而goto指令則不受限制,可跳到一個PAGE之前、後半部。
    PROGRAM MEMORY位址7FF是reset後第一個被執行的指令,正常情況下放入goto指令,而且STATUS WORD REGISTER bit 6, 5在 reset後全變為0,所以這個goto指令會使程式跳到PAGE 0去執行。至於要goto到何處?我們先以main 的label來代表,下文再繼續討論。
    結構化的程式撰寫是由主程式呼叫許多副程式組成的,為了能善用這四個PAGE,又不要讓程式在呼叫副程式時或做goto之前也要同時注意PAGE的設定值,我對PAGE 0做以下安排:PAGE 0的前半部先存放所有的第一階(即主程式直接呼叫的)副程式,接下來才存放主程式,上一段所提及的label—main就是安排在這個地方;整段主程式只能放在PAGE 0內,否則分置於兩個PAGE內的goto指令前需有不同的PAGE控制,此舉不但麻煩又易出錯,尤其是尚在發展更改中的程式,更難掌握。
    當上述的第一階副程式太大或太多,以致無法全部放入PAGE 0的前半部時,或是會造成主程式分跨於PAGE 0與PAGE 1時,就要將部分副程式的"身體"移到別的PAGE中,但"頭"仍需保留在PAGE 0的前半部,"頭"是個重要的媒介,其任務就是要把副程式導引到正確的PAGE上執行;而被移走的副程式其"尾"(retlw之前)需加上指令,把PAGE的控制轉回PAGE 0;如此安排,主程式就不用管它所呼叫的副程式"主體"究竟位於哪個PAGE上了。請參考如下範例:
LIST p=16c57
;****************************************************************
ORG 0 ;page 0前半部
;****************************************************************
init: ;副程式的"頭
bsf STATUS,5 ;page selector point to page 1
goto sub1_1
;------------------------------------------------------------------------------------------------
tx: ;副程式的"頭
bsf STATUS,6 ;page selector point to page 2
goto sub2_1
;------------------------------------------------------------------------------------------------
rx: ;副程式的"頭
bsf STATUS,6 ;page selector point to page 2
goto sub2_2
;------------------------------------------------------------------------------------------------
rd_eeprom: ;副程式的"頭
bsf STATUS,5 ;page selector point to page 3
bsf STATUS,6
goto sub3_1
;------------------------------------------------------------------------------------------------
………………
;其它的第一階副程的"頭"
;=========================================================
main:
;主程式
………………
call init ;直接呼叫,不必管PAGE問題
………………
call rd_eeprom ;直接呼叫,不必管PAGE問題
………………
call tx ;直接呼叫,不必管PAGE問題
………………
call rx ;直接呼叫,不必管PAGE問題
………………
;****************************************************************
ORG 0x200 ;page 1前半部
;此前半部可用以放置第二階副程式,而且是僅接受PAGE 1程式的呼叫;同樣的,這些副程式進入點也需全部位於PAGE 1的前半部,否則會被呼叫不到;如此規劃,對PAGE的控制才會單純。
;------------------------------------------------------------------------------------------------
rout1_1:
………………
retlw 0 ;如此規劃不必更改PAGE控制
;------------------------------------------------------------------------------------------------
rout1_2:
………………
retlw 0 ;如此規劃不必更改PAGE控制
;=========================================================
sub1_1: ;副程式的"身體"
………………
call rout1_1
………………
call rout1_2
………………
bcf STATUS,5 ;page selector point to page 0
retlw 0
;****************************************************************
ORG 0x400 ;page 2前半部
;此前半部的規劃與PAGE 1同
;------------------------------------------------------------------------------------------------
sub2_1: ;副程式的"身體"
………………
bcf STATUS,6 ;page selector point to page 0
retlw 0
;------------------------------------------------------------------------------------------------
sub2_2: ;副程式的"身體"
………………
bcf STATUS,6 ;page selector point to page 0
retlw 0
;****************************************************************
ORG 0x600 ;page 3前半部
;此前半部的規劃與PAGE 1同
;------------------------------------------------------------------------------------------------
sub3_1: ;副程式的"身體"
………………
bcf STATUS,5 ;page selector point to page 0
bcf STATUS,6
retlw 0
;****************************************************************
ORG 0x7FF ;reset vector
goto main
;****************************************************************
END

    上例中將PAGE 1、2、3的前半部優先放置第二階副程式,而且此副程式只由同一PAGE中的第一階副程式所呼叫使用;若其它PAGE也有第一階副程式需用到此第二階副程式,那就把有此需要的第一階副程式搬來同一PAGE吧。如此用心良苦有以下幾個好處:1、第一階副程式可直接call第二階副程式,不用改變PAGE的控制,2、第二階副程式執行結束時只需retlw,也不用改變PAGE的控制,3、PAGE的管理單純,不易出錯,4、整個程式碼可減少bcf SATUS,5、bcf STATUS,6、bsf STATUS,5、bsf STATUS,6的數量;當主程式也有必要直接呼叫此第二階副程式時,可以有兩種做法,第一種做法可以保持程式PAGE管理的一致性,就是為主程式另外設計一個第一階副程式,來間接呼叫這個第二階副程式,這會增加5個(若這個第二階副程式在PAGE 3則需再加2個)指令及其執行時間,第二個做法就是破壞原則,由主程式直接呼叫,但在call指令的前後需加上PAGE控制,這種做法有其缺點,就是當此第二階副程式被移到別的PAGE時,主程式內所有為呼叫該第二階副程式所做之PAGE控制,全需因應修改,而且呼叫的次數愈多,PAGE控制也跟著多,修改起來也更費事且易出錯;兩種做法各有其利弊,何者適用則全由閣下視情況自行判斷選擇了。
     程式組譯(assemble)完一定要開啟listing檔(副檔名.lst),看看有無跨PAGE的現象,有的話就要調整該PAGE內一部分的副程式到別的PAGE,同時被搬動過的副程式的"頭"及"尾"也需因應修改,同時要注意的是,是否把相對應的第二階副程式也一齊搬動;另外要看看副程式(第一階或第二階)之進入點,有沒有落於每個PAGE的前半部(即Address的bit 8為0的區域),沒有的話也要調整以消除此現象,不然會造成呼叫不到的bug。
現在將以上程式PAGE安排原則總結如下:
一、PAGE 0的前半部先放第一階副程式的"頭"(若空間足夠也可放整個副程式),"頭"負責把PAGE控制轉到該副程式的"身體"所座落之PAGE。
二、接下來放置主程式,主程式需全部置於PAGE 0內。
三、第一階副程式的"身體"可置於任一PAGE內,該副程式的"尾"負責把PAGE控制轉回PAGE 0。
四、第二階副程式與呼叫它的第一階副程式放在同一PAGE內。
五、呼叫第二階副程式不用改變PAGE控制(例外:主程式的呼叫);第二階副程式的"尾"也不用改變PAGE控制。
六、所有的副程式,不管是第一階或第二階,其進入點皆需位於每一PAGE的前半部。
如此安排後,對副程式的呼叫均不需處理PAGE控制,此控制是由副程式的"頭"及"尾"處理掉了;而主、副程式當中的goto指令就可安心使用,不虞會GOTO到錯誤的PAGE上。
以上安排是不是會讓您安心撰寫程式而不用擔心PAGE的控制呢?如果您發現到更好的方法也請不吝指教,謝謝!                    

引用地址:靈活使用PIC16C57单片机的PROGRAM MEMORY

上一篇:PIC16F887与MPLAB之应用设计
下一篇:PIC单片机开发的若干问题

小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved