MCS-51的数据存储器,分为片外RAM和片内RAM。片外RAM地址空间为64KB,地址范围是0000H~FFFFH。片内RAM地址空间为128B(51子系列)/256B(52子系列),地址范围是00H~7FH(51子系列)/FFH(52子系列),片内RAM与片内特殊功能寄存器SFR统一编址。图2-8为MCS-51单片机的数据存储器的编址结构。
图2-8 MCS-51单片机的数据存储器的编址结构
1.片内数据存储器(00H~7FH/FFH)
在MCS-51单片机中,尽管片内数据存储器的容量不大,但它的功能多,使用灵活。片内数据存储器除了RAM块外,还有特殊功能寄存器(SFR)块。其中对于51子系列,RAM块有128字节,编址为00 H~7FH,SFR也占128个字节,编址为80H~FFH;对于52子系列,RAM有256字节,编址为00 H~FFH,SFR也有128字节,编址为80 H~FFH。52子系列RAM的后128个字节与SFR的编址是重叠的,它们可通过间接寻址、直接寻址两种不同的寻址方式来相区分。
片内数据存储器共有128B RAM(51子系列)/256B RAM(52子系列),再加上128B SFR。片内数据存储器按功能分成4个部分:①工作寄存器组区;②位寻址区(也称位地址区);③一般RAM区(也称数据缓冲区或通用RAM区或用户RAM区),其中还包含堆栈区;④特殊功能寄存器区。其中①~③为片内RAM区,它的内部配置情况见表2-5。
(1)工作寄存器区。工作寄存器区是指00 H~1FH区,共分4个组,每组有8个单元,共32个内部RAM单元。即寄存器0组:地址00H~07H;寄存器1组:地址08H~0FH;寄存器2组:地址10H~17H;寄存器3组:地址18 H~1FH。每个工作寄存器组都有8个寄存器,分别称为R0,R1,…,R7,如表2-6。工作寄存器常用于存放操作数中间结果等。由于它们的功能及使用不作预先规定,因此称之为通用寄存器。
表2-5 MCS-51系列单片机片内RAM的配置情况
表2-6 RS1、RS0与片内工作寄存器组的对应关系
程序运行时,只能有一个工作寄存器组作为当前(或称活动)工作寄存器组,其他各组可以作为一般的数据缓冲区使用。当前工作寄存器组的选择是由特殊功能寄存器中的程序状态字PSW的RS1(PSW.4)、RS0(PSW.3)两位决定的。可以对这两位进行编程,以选择某一工作寄存器组。单片机上电复位后,RS1=RS0=0,因此工作寄存器为0组。
(2)位地址区。位寻址区是指20 H~2FH单元,共16个单元。它有双重寻址功能,其一是位寻址区,可以进行位寻址操作,每1位都可当作软件触发器,其作用与PSW中的F0相同,由程序直接进行位处理,通常可以把各种程序状态标志、位控制变量存于位寻址区内。位寻址区的16个单元(共计128位)的每1位都有一个8位表示的位地址,位地址范围为00H~7FH,如表2-5所示;其二是位寻址的RAM单元也可以同普通RAM单元一样作为一般的数据缓冲区按字节寻址操作。
实际上,位寻址空间一部分在上述的内部RAM的20H~2FH单元内,共128位;另一部分在SFR的空间内。MCS-51具有布尔处理机功能,这个位寻址区可以构成布尔处理机的存储空间。这种位寻址能力是MCS-51的一个重要特点。
(3)一般RAM区(数据缓冲器区)。对于51子系列,30 H~7FH是一般RAM区,共80字节;对于52子系列,一般RAM区从30H~FFH单元,共80+128=208字节。另外,对于前面工作寄存器区、位寻址区中未用的单元也可作为用户RAM单元使用。
一般RAM区用于存放用户数据,只能按字节存取。通常这些单元可用于中间数据的保存,也用作堆栈的数据单元。
MCS-51单片机中,堆栈是用片内RAM的一段区域,在具体使用时应避开工作寄存器、位寻址区,一般设在30H以后的单元,如工作寄存器和位寻址区未用,也可开辟为堆栈。堆栈是个特殊的存储器,主要功能是暂时存放数据和地址,用来在子程序调用、中断服务处理等场合保护断点和现场。它的特点是先进后出、后进先出,这里的“进”与“出”是指进栈与出栈。
(4)特殊功能寄存器。特殊功能寄存器(Special Function Register,简称SFR)也称专用寄存器,它们专门用于控制、管理和监视片内算术逻辑部件ALU、并行I/O口、串行口、定时/计数器、中断系统等功能模块的工作,实际上SFR是各个功能部件的控制寄存器和状态寄存器。用户在编程时可以给其设定值,但不能移作它用。各个SFR离散地分布在高128B(80H~FFH)地址空间,与片内数据存储器RAM统一编址(注意:除了PC以外,PC是单独编址的),其中,字节地址能被8整除(即16进制地址码尾数为0或8)的单元还具有位寻址的能力。51子系列有18个特殊功能寄存器,其中3个为双字节,共占用21个字节,11个有位地址(仅83位有效)。52子系列有21个特殊寄存器,其中5个为双字节,共占用26个字节,12个有位地址(仅91位有效)。
它们的分配情况如下:①CPU专用寄存器:累加器A(E0H)、寄存器B(F0H)、程序状态寄存器PSW(D0 H)、堆栈指针SP(81 H)、数据指针DPTR(82H、83 H);②并行接口:P0~P3(80 H、90H、A0 H、B0 H);③串行接口:串口控制寄存器SCON(98 H)、串口数据缓冲器SBUF(99H)、电源控制寄存器PCON(87H);④定时/计数器:方式寄存器TMOD(89 H)、控制寄存器TCON(88 H)、初值寄存器TH0、TL0(8BH、8AH)和TH1、TL1(8DH、8CH);⑤中断系统:中断允许寄存器IE(A8H)、中断优先级寄存器IP(B8 H);⑥定时/计数器2相关寄存器(仅52子系列有):定时/计数器2控制寄存器T2CON(CBH)、定时/计数器2自动重装寄存器RLDL和RLDH(CAH和CBH)、定时/计数器2初值寄存器TH2和TL2(CDH和CCH)。表2-7为各种SFR的名称、符号、地址及位地址表。
表2-7 SFR地址映象
续表
注 凡标“*”的SFR仅52子系列才有;表中带有位名称或位地址的SFR可能按字节方式或位方式处理。
对SFR的几点说明:
1)21/26个可字节寻址的特殊功能寄存器是不连续地分散在内部RAM高128单元之中,共83/91个可寻址位。尽管还剩余许多空闲单元,但用户并不能使用。
2)程序计数器PC不占据RAM单元,它在物理上是独立的,因此它是不可寻址的寄存器。
3)对特殊功能寄存器只能使用直接寻址方式,书写时既可使用寄存器符号,也可使用寄存器的地址。
下面仅介绍与单片机内部的运算器ALU、控制器CU相关的SFR寄存器(专用寄存器)。与并行I/O口、串行口、定时/计数器、中断系统等功能模块相关的SFR寄存器将在后面章节中介绍。
1)程序计数器(PC)。我们已经知道程序计数器(Program Counter,简称PC)是一个16位的计数器,它的作用是控制程序的执行顺序。其内容为将要执行指令的地址,寻址范围达64KB。程序计数器PC有自动加“1”的功能,从而实现程序的顺序执行。注意:PC虽然属于SFR的一部分,但它是单独编址的,它没有与21/26个SFR一起统一编址,也就是说它没有8位SFR地址,它是不可寻址的,因此用户无法对它进行读写,但可以通过转移、调用、返回等指令改变其内容,以实现程序的转移。单片机中这样设计PC的地址的目的主要是防止用户随意篡改PC值,以及防止现场干扰信号改变PC值,从而使程序跳转“跑飞”到非用户程序设计的地方。
2)累加器(ACC)。累加器(Accumulator,简称ACC或A)是CPU内部特有的8位寄存器。它的字节地址为E0 H,其位地址为E0 H~E7H。常用于存放参加算术或逻辑运算的两个操作数中的一个及运算结果,即用于存放目的操作数,例如:
该指令的含义是以累加器A内容作为被加数,与存放在内部RAM的20H单元中内容相加,相加后的结果,再存放到累加器A中。
3)寄存器B。寄存器B也是CPU内特有的一个8位寄存器,它的字节地址为F0H,其位地址为F0 H~F7H。它主要用于乘法和除法运算。在乘法运算中,被乘数放在累加器A中,乘数放在寄存器B中,运算后,积的高8位存放寄存器B中,积的低8位放在累加器A中。例如:
在除法运算中,被除数放在累加器A中,除数放在寄存器B中。运算后,商放在累加器A中,而余数放在寄存器B中。
4)程序状态字寄存器(PSW)。程序状态字寄存器(Program Status Word register,简称PSW)是一个8位的特殊寄存器,它的字节地址为D0 H,其位地址为D0 H~D7 H。程序状态字寄存器也称为“标志寄存器”,它由一些标志位组成,用于存放ALU运算结果的特征和处理状态,以供程序查询和判别。PSW中有些位的状态是根据程序执行结果,由硬件自动设置的,而有些位的状态则使用软件方法设定。PSW的位状态可以用专门指令进行测试,也可以用指令读出。一些条件转移指令将根据PSW某些位的状态,进行程序转移。PSW中各位的具体定义见表2-2和表2-3。
5)堆栈指针(SP)。堆栈指针(Stack Pointer,简称SP)是一个8位寄存器,它的字节地址为81 H,无位地址。它用于存放栈顶地址。每存入(或取出)一个字节的数据,SP就自动加1(或减1)。SP始终指向新的栈顶。
堆栈指针操作是在内存RAM区中专门开辟出来的、按照“先进后出,后进先出(Last In First Out,简称LIFO)”的原则进行数据存取的一种工作方式。堆栈有栈顶和栈底,其中,由于栈底固定不变,不需要设置指针;而栈顶为最后推入堆栈的数据所在的存储单元,由于栈顶是随堆栈中数据的变化而浮动变化,需要采用堆栈指针SP来指示栈顶所处的位置。当堆栈中没有数据时,栈顶与栈底两者是重叠的,SP指向堆栈的最下端(即栈底);而当向堆栈推入数据后,栈顶向上生长(即地址增加),SP也向上生长。在进行堆栈操作之前,先用指令给SP赋值,以规定栈区在RAM区的起始地址(即栈底)。当数据推入栈区后,SP的值也自动随之变化。
堆栈操作有两种方式:一种是指令方式,采用堆栈操作指令进行“进栈/出栈”操作;另一种是自动方式,在调用子程序或产生中断时,返回地址(主程序的下一条指令地址,简称断点地址或断点)自动进栈;程序返回时,断点地址再自动弹回PC。自动方式是硬件自动完成的,此方式在完成子程序嵌套和多重中断处理中是必不可少的。为保证逐级正确返回,进入栈区的“断点”数据应遵循“先进后出,后进先出”的原则。
在MCS-51单片机中,SP可以指向内部RAM中任一单元,且堆栈向上生长(注意,8086CPU中的堆栈是向下生长的),即将数据压入堆栈后,SP寄存器内容增大。假设SP当前值为2FH,则入栈指令“PUSH B”将寄存器B内容压入堆栈的执行过程如图2-9所示。出栈指令“POP B”指令的执行过程如图2-10所示。
图2-9 PUSH B指令的执行过程
图2-10 POP B指令的执行过程
数据入栈的操作过程为:先将SP加1,即(SP)←(SP)+1,然后将要入栈的数据存放在SP指定的存储单元中。而将数据从堆栈中弹出时,先将SP寄存器指定的存储单元内容传送到POP指令给定的寄存器或内部RAM单元中,然后SP减1,即(SP)←(SP)-1。可以看出堆栈的底部是固定的,而堆栈的顶部则随着数据入栈和出栈而上下浮动。
MCS-51系统复位后,SP寄存器被初始化为07H,当有数据进入堆栈时,将从08 H单元开始存放,这一般是不允许的,因为08 H~1FH属于工作寄存器区1~区3(注意:工作寄存器区0的地址为00H~07H),不宜占用;20H~2FH是位地址区,也需要部分或全部保留。因此,必须通过数据传送指令重新设置SP的初值,将堆栈底部设在30 H~7FH(51子系列)/FFH(52子系列)之间,例如:MOV SP,#60H,即将堆栈指针设在60H单元。
SP的内容一经确定,堆栈的位置也就跟着确定下来,由于SP可初始化为不同值,因此堆栈位置是浮动的。CPU内30H~7FH/FFH单元既可以作为堆栈区,同时也是用户数据存储区。由于单元数量有限,必须充分利用,因此应认真考虑将堆栈底部设在何处。随着入栈数据的增多,当SP超出7FH(51子系列)或FFH(52子系列)时发生上溢,这将出现不可预料的后果。因此,在设置SP初值时,必须考虑堆栈最大深度。子程序或中断嵌套层数越多,所需的堆栈深度就越大。为了避免堆栈顶部进入用户的数据存储区而造成混乱,一般将堆栈设在用户的数据存储区之上。
若在某一51子系列的应用系统中,需要32个字节作为用户数据存储区(如30H~4FH),则初始化时将堆栈底部设在50 H(指令为MOV SP,#4FH,即将SP初值为4FH),即堆栈深度最多为48个字节(50 H~7FH)。对于具有高128字节的52子系列来说,最好将堆栈区设在80 H~FFH之间的高128字节内部RAM中,而将具有直接寻址功能的低128字节内部RAM作为用户数据存储区,以便可用多种寻址方式存取用户数据。例如,预计某系统所需最大堆栈深度为32字节,可通过如下指令将栈底设在0E0H处(指令为MOV SP,#0DFH,即将SP初值为0DFH)。
6)数据指针DPTR。数据指针(Data Poin Ter Register,简称DPTR)是一个16位的专用寄存器,由数据指针高8位DPH和数据指针低8位DPL组成,它们的字节地址为82 H和83H,它们无位地址。编程时,DPTR既可以按16位寄存器使用,也可以按两个8位寄存器分开使用。DPTR通常在访问外部RAM时作地址指针使用。由于外部RAM的寻址范围为64KB,故把DPTR设计为16位。由于DPTR是16位的寄存器,因此通过DPTR寄存器间接寻址方式可以访问0000H~FFFFH全部64KB的外部数据存储器空间。(www.xing528.com)
例如,可用如下指令将累加器A内容传送到外部RAM的1000 H单元中。
MOV DPTR,#1000H ;将外部RAM地址1000H以立即数寻址方式传送到DPTR寄存器
MOVX@DPTR,A ;将累加器A的内容传送到DPTR寄存器内容所指定的外部RAM
DPTR也可以指向程序存储器ROM,此时用来指向ROM中的固定表格的某一单元。
如果仅需改变外部RAM的低8位地址,高8位地址不变,也可采用R0或R1作为外部RAM间接寻址的数据指针。
(5)单片机RAM的数据传送及寻址方式。
1)128B的内部RAM存储器(00H~7FH)。对于低128B的内部RAM存储器(00H~7FH),可以通过直接寻址方式或寄存器间接寻址方式读写,例如:
MOV 30H,#45H ;直接寻址方式
MOV@R0,#45H ;寄存器间接寻址方式
上面的第1条指令将立即数45H写入内部数据存储器地址为30H的单元中。所谓直接寻址,就是在指令中直接给出了内部RAM单元的地址编码。
上面的第2条指令将立即数45H写入由R0寄存器内容指定的内部RAM单元中。如果该指令执行前,R0的内容为30H,则上述两条指令执行后,效果相同。所谓寄存器间接寻址,就是将内部RAM的地址存放在寄存器R0或R1中。
2)21/26个特殊功能寄存器SFR。对于特殊功能寄存器只能使用直接寻址方式访问,例如:
MOV 0E0H,#45H ;直接给出累加器ACC的地址(即为0E0H),也可把此指令中0E0H改为A
MOV 90H,#0FFH ;直接给出P1口的地址(即为90H),也可把此指令中90H改为P1
由于每一个特殊功能寄存器均有一个与之相应的寄存器名,因此在指令中最好直接引用特殊功能寄存器名,如上例中用A、P1取代对应的特殊功能寄存器地址。
其实,对于特殊功能寄存器来说,用直接地址和寄存器名寻址没有区别,指令汇编时,将自动通过查表方式将寄存器名换成直接地址。
3)高128字节内部RAM存储器(80 H~FFH)。对于具有256字节内部RAM的52子系列单片机来说,高128字节内部RAM地址空间与特殊功能寄存器SFR的地址重叠,读写时需要通过不同的寻址方式加以区别。一般规定用寄存器间接寻址方式访问高128字节(80H~FFH)的内部RAM;用直接寻址方式访问特殊功能寄存器。如在52子系列单片机中,“MOV 0E0 H,#45 H”指令的含义是将立即数45 H写入累加器A中,与“MOV A,#45H”含义相同,而不是把立即数45 H写入内部RAM的0E0 H单元中。将立即数45 H传送到内部RAM的0E0H单元中只能通过如下指令进行:
MOV R0,#0E0H ;将内部RAM地址0E0 H写入R0寄存器中
MOV@R0,#45H ;高128字节内部RAM只能通过寄存器间接寻址访问
4)位寻址区。MCS-51系列单片机既是8位机,同时也是一个功能完善的1位机。作为1位机时,它有自己的CPU、位存储区(位于内部RAM的20H~2FH单元)、位寄存器(如将进位标志CY作为“位累加器”)以及具有完整的位操作指令(包括置1、清零、非(取反)、与、或、传送、测试转移等)。
对于位存储器(即20H~2FH单元中的128个位),只能采用直接位寻址方式确定操作数所在的存储单元,如:
MOV C,20H ;位传送指令,将位地址20H单元内容传送到位累加器C中,注意:位指令中,CY被简写为C
CLR 20H ;位清零指令,即将位地址20H单元清零
SETB 20H ;位置1指令,即将位地址20H单元置1
CPL 20H ;位取反操作,即将位地址20H单元内容取反
ORL C,20H ;位或运算,20H位单元与位累加器C相或结果存放在位累加器C中
ANL C,20H ;位与运算,20H位单元与位累加器C相与结果存放在位累加器C中
对于具有位地址的特殊功能寄存器中的位,除了使用位地址寻址外,还可以使用“位定义名”或“寄存器名.位”表示,作用完全等效。如将程序状态字寄存器PSW中的D3位置0,可以用:
CLR D3H ;位地址方式
CLR RS0 ;位定义名方式
CLR PSW.3 ;“寄存器名.位”方式
2.片外数据存储器(0000H~FFFFH)
MCS-51单片机片内有128字节(51子系列)或256字节(52子系列)的RAM,当这些RAM不够时,可在外部扩展外部RAM,片外RAM一般由静态RAM(SRAM)构成,其容量大小由用户根据需要而定,扩展的外部RAM最多64KB,地址范围为0000 H~FFFFH,通过DPTR作指针间接寻址方式访问。对于高8位地址不变,而低8位地址变化的256字节(也称低端的256字节),低8位的地址范围为00H~0FFH,此时可通过R0和R1间接寻址方式访问,而高8位地址可直接送入到P2口即可。
另外,外部RAM和扩展的外部设备(I/O端口)是统一编址的,所有的外扩I/O口要占用64KB中的地址单元,它们用访问片外数据存储器RAM的方法访问。
实际上,MCS-51单片机的内部RAM与内部I/O端口(即SFR)是采用统一编址的,外部RAM与外部I/O端口也是采用统一编址的。需要说明的是:
(1)64KB程序存储器ROM和64KB片外数据存储器RAM的地址空间都为0000 H~FFFFH,它们的地址空间是完全重叠的,那么它们是如何区分的呢?
MCS-51单片机是通过不同的信号来对片外RAM和ROM进行读、写的,片外RAM的读、写通过信号来控制,而ROM的读通过PSEN信号控制,通过用不同的指令来实现,片外RAM用MOVX指令,ROM用MOVC指令。
(2)片内RAM和片外RAM的低256字节的地址空间是重叠的,它们又是如何区分呢?
片内RAM和片外RAM的低256字节通过不同的指令访问,片内RAM用MOV指令,片外RAM用MOVX指令。因此在访问时不会产生混乱。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。