单片机 > 单片机程序设计 > 详情

AT89C51程序存储器不用I/O口的扩展技术

发布时间:2023-05-04 发布时间:
|

简介:介绍一种采用分页式管理思想,在不增加地址线的前提下,将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等,可以单独外扩一个存储区作为页表存储器。


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32学习笔记4:外部中断