简介:介绍一种采用分页式管理思想,在不增加地址线的前提下,将AT89C51单片机程序存储器进行超大规模扩展的方法;给出在超大规模程序存储空间中执行顺序程序,执行长跳转、子程序长调用或中断服务时的通用编程模式。
1 扩展方法
1.1 扩展思想
AT89系列单片机对程序存储器的基本寻址能力最大为64 KB。若要进行超大规模的存储空间扩展,最直接的方法是增加地址线(每增加1条,存储空间扩大1倍);但是由于单片机的I/O资源有限,靠增加地址线来扩展存储空间,势必会削弱单片机的I/O功能。下面以AT89C51单片机为例,介绍一种在不增加地址线的前提下,通过向单片机的内部Flash存储器写入几条简单的转换指令,来实现程序存储器大规模扩展的方法。基本思想是:采用分页式管理思想,将AT89C51内部4 KB的Flash存储器视为页表空间,将要扩展的超大规模程序存储器按60 KB为一个页面分成若干个页。当要执行某一页面中的程序段时,首先运行页表(内部Flash存储器)中的页面选择指令来选通相应的页,然后转去执行页中的程序段。该程序段执行完,程序返回到页表。
1.2 扩展系统硬件电路说明
采用线选法扩展8页程序存储器的硬件逻辑电路如图1所示。74LS373是8位地址锁存器,用于锁存的地址/数据复用口P0送出的低8位地址。外部扩展的超大规模存储空间为480 KB,以60 KB为1页被分成了8页,页面地址锁存/缓冲器由2个8位的上升沿锁存器74LS273(1)和74LS273(2)组成,它们共用同一地址FFFFH(注意:读/写外部RAM时,禁止使用该地址)。
图1中,各片27512的页面地址通过执行内部Flash存储器中的页面选择指令“MOVX @DPTR,A”产生(累加器A中存放页面地址)。当执行指令“MOVX @DPTR,A”时,P0口先送低8位地址到地址锁存器74LS273(1)中。
只有当低8位地址为FFH时,与门U1才输出1;同样,只有当P2口送出的高8位地址为FFH时,与门U2才输出1。也就是说,只有写外部RAM的为FFFFH时,与门U3才被打开,而写外部RAM的其余地址单元时U3被关闭。当与门U3被打开时,U3的输出随AT89C51的WR引脚信号的变化而变化。P0口送出低8位地址后,WR由1变为0,U3输出也由1变为0,接着从P0口送出页面地址至74LS273(1);当WR由0变为1时,U3输出也由0变为1,上升沿将P0口送出的页面地址锁存到74LS273(1)中。如果累加器A中的数据为FEH,则74LS273的输出端Q0=0、Q1~7=1,这时与Q0端相连的27512芯片被选通;如果累加器A中的数据为FDH,则与Q1端相连的27512被选通。依此类推,通过改变页面选择指令里累加器A中的数据,便可任意选通一片27512。可见,1#~8#存储器页的页面地址依次为FEH、FDH、FBH、F7H、EFH、DFH、BFH、7EH。
当前存储器芯片的页面地址可以通过读页面地址锁存/缓冲器得到。由图1可知,当执行读存储器页面地址指令“MOVXA,@DPTR”时,P0口先送低8位地址到地址锁存器74LS273(1)中,只有当它为FFH时,与门U1才输出1;同样,只有当P2口送出的高8位地址为FFH时,与门U2才输出1。也就是说,只有读外部RAM的地址为FFFFH时,与门U4才被打开,而读外部RAM的其余地址单元时U4被关闭。当与门U4被打开时,U4的输出随AT89C51的RD引脚信号的变化而变化。P0口送出低8位地址后,RD由1变为0,U4输出也由1变为0;当RD由0变为1时,U4输出也由0变为1,上升沿将当前页面地址(原来锁存在74LS273(1)中的页面地址,或FEH、或FDH、或FBH、或F7H、或EFH、或DFH、或BFH、或7EH)从缓冲器74LS273(2)中读出。
2 超大规模扩展程序存储器的使用
2.1 顺序程序的存储和执行
假如现在有一较大的顺序程序,可以将其分段依次写入图1中的8个页(1#~8# EPROM 27512)内,且将每个页中的程序段视为子程序处理,设各子程序首址依次为FIRROM、SECROM、THIROM、FOVROM、FIFROM、SIXROM、SEVROM、EIGROM,并在每个程序段末尾加一条返回指令RET。同时在AT89C51内部Flash存储器中写入如下的程序存储页转换程序段,便可连续执行8个页(1#~8#外部EPROM 27512)中的程序了。
ORG0000H
LJMPCALTAB
……
ORGCALTAB
CALFIR:MOVDPTR,#FFFFH;取74LS273的地址到DPTR
MOVA,#FEH;1# 27512选通信号数据送A
MOVX@DPTR,A;选通1#27512芯片
LCALLFIRROM;去执行1# 27512中程序段
……
CALEIG:MOVDPTR,#FFFFH;选通8#27512芯片
MOVA,#7FH
MOVX@DPTR,A
LCALLEIGROM;去执行8#27512中程序段
SJMP$
在执行某一页外扩程序存储区中的程序前,系统先运行内部Flash存储器中对应页面选择程序段来选通相应的页。如执行第1页(1# 27512)中的程序前,先运行CALFIR程序段,然后转去执行第1页(1# 27512)中的程序。执行完该页中的程序段后,通过页尾的返回指令RET,地址指针PC回指到内部Flash存储器中“LCALLFIRROM”指令的下一条指令,接着再运行内部Flash存储器中的SECROM段程序,于是又选通了第2页(2# 27512)程序存储区,并转去执行其中的程序段。依此类推,便可顺序执行完8个页面(1#~8#27512)中的所有程序。
2.2 大规模程序的存储和使用
无论多么复杂的程序从整体上仍然可以看成是顺序程序,因此一个包含分支、子程序调用、中断服务的大规模程序,仍然要按顺序程序的存储方法进行存储和处理。问题在于如何实现程序的页间长跳转、页间子程序长调用和页间中断子程序自动调用。下面给出一种通用方法。
(1) 对内部Flash存储器的编程
在内部Flash存储器中,除写入上述存储器页面选择信号的产生程序外,还要写入页间跳转、一般子程序页间调用以及中断子程序页间调用的公共引导程序。其模式如下:
JORCPROG:MOVDPTR,#FFFFH
POPACC
MOVX@DPTR,A
RET
(2)程序页间跳转的实现
设系统在执行当前存储器页内程序时,需转去执行其他存储器页(也可在当前页内)中标号为JTOADDR的程序段。在具体编程时,需要在当前页内利用下面程序段来实现页间跳转的引导:
PJMP: MOVDPTR,#JTOADDR;目标地址
PUSHDPL;入栈
PUSHDPH
MOVA,#JMPPAGE;目标程序所在页面地址
PUSHACC
LJMPJORCPROG;执行公共转换程序
(3) 一般子程序页间调用的实现
设系统在执行当前存储器页内程序时,需要调用其他存储器页(也可是前页)内标号为CALADDR的子程序。在当前页内需要用以下程序段完成页间调用的引导:
PCALL:MOVDPTR,#OWNADDR ;断点地址入栈
PUSHDPL
PUSHDPH
MOVDPTR,#FFFFH
MOVA,@DPTR;读当前存储器页面地址
PUSHACC;页面地址入栈
MOVDPTR,#FORCPROG;公共转换程序地址
PUSHDPL
PUSHDPH
MOVDPTR,#CALADDR;被调子程序地址
PUSHDPL;地址入栈
PUSHDPH
MOVA,#CALPAGE;被调用子程序所在页面地址
PUSHACC
LJMPJOTCPTOG;执行公共转换程序返回断点
OWNADDR:……;断点
(4) 中断子程序页间调用的实现
AT89系列单片机的中断调用,实质是机器自动执行的一次硬件长调用,等同于执行“LCALLaddr16”。与一般子程序长调用不同的是,这里的“addr16”是系统约定的,即中断入口地址。因此在超大规模程序存储器中,当所要执行的中断服务程序和断点不在同一存储器页(也可在同页)时,中断响应后也要通过执行相应页面转换操作,才能完成正确调用和准确返回。但是,由于中断请求何时产生完全取决于中断源的状态,在执行程序时无法预测,所以为保证有效的中断请求都能及时得到响应,中断调用引导程序也写在内部Flash存储器中。
下面以外部中断0(INT0)为例,给出引导程序的模式。设外部中断0被响应后,需调用标号为INT0ADDR的中断服务程序。该中断服务程序所在的存储器页地址为INT0PAGE,引导程序模式如下:
ORG0003H
LJMPINT0PROG
ORG002BH
INT0PROG:MOVDPTR,#FFFFH
MOVXA,@DPTR;读当前存储器页面地址
PUSHACC;页面地址入栈
MOVDPTR,#JORCPROG
PUSHDPL
PUSHDPH
MOVDPTR,#INT0ADDR
PUSHDPL
PUSHDPH
MOVA,#INT0PAGE
PUSHACC
LJMPJORCPROG
其他中断的引导程序与此相仿,不再重述。
在软件编程中使用的CALPAGE、INT0PAGE等标号,是某一页的页面地址,具体编程时是存储器页面地址FEH、FDH、FBH、F7H、EFH、DFH、BFH、7EH中的一个。
结语
以上论述了AT89C51单片机程序存储器超大规模扩展方法,以及在大规模程序空间实现程序跳转、子程序调用和中断响应的通用编程模式。这种程序跳转、子程序调用和中断响应的通用编程模式,也适用于同一存储器页(64 KB)内的程序跳转、子程序调用和中断响应;但由于引导转换过程需要占用一定的时间,所以在实时性要求较高的系统中,若能够确定是在同一页内,则应采取单一指令的方法。
对于其他系列的单片机,如MCS51系列等,只要含有内部程序存储器,均可采取上述方法实现程序存储器超大规模扩展和灵活使用;对于不含内部程序存储器的单片机,或虽然含内部程序存储器,但用户不能对其编程的单片机,如8051等,可以单独外扩一个存储区作为页表存储器。
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』