二、数据存储器
单片机的数据存储器主要用于存放经常要修改的中间运算结果、数据暂存和缓冲、标志位等,通常是由随机存取存储器RAM组成。数据存储器空间也分成片内和片外两个部分,即片内RAM和片外RAM。片内数据存储器与片外数据存储器不论在逻辑上还是在物理上都是分开的,它们是通过不同的寻址方式来区分的。
89C51片外数据存储器空间为64KB,地址为0000 H~FFFFH;片内数据存储器空间为256字节,地址为00H~FFH。
(一)片外RAM
89C51单片机的外部数据存储器最多可以扩展至64KB。如图2-12所示,89C51片外数据存储器与片内数据存储器空间的低地址部分(00H~FFH)是重叠的,MCS-51单片机采用不同的指令助记符来区分片内、片外RAM两个地址空间。如89C51有MOV和MOVX两种指令,用以区分片内、片外RAM空间。片内RAM使用MOV指令访问,片外64KB RAM空间使用MOVX指令(使引脚或
信号有效)访问。
MCS-51单片机片内RAM容量有限,如89C51单片机片内RAM只有256字节。若需要扩展片外RAM,则可外接2KB/8KB/32KB静态RAM芯片6116/6264/62256。
(二)片内RAM
89C51片内数据存储器共有256个单元,其地址为8位,寻址范围为00H~FFH。通常把这256个单元按其功能划分为两个部分,即低128个单元(字节地址范围为00H~7FH)和高128个单元(字节地址范围为80H~FFH)。其中低128个单元能作为数据存储器供用户使用,而高128个单元则被特殊功能寄存器SFR占用,如图2-13所示。
图2-13 片内数据存储器的配置
1.低128字节RAM
按其用途可以划分为三个区域,如图2-14所示。其中00H~1FH地址空间为通用工作寄存器区,20H~2FH地址空间为位寻址区,30H~7FH地址空间为用户RAM区。
图2-14 低128字节RAM区
(1)通用工作寄存器区。89C51指令系统中使用了8个工作寄存器(又称为通用寄存器),即R0~R7。每个工作寄存器均为8位。系统为这8个工作寄存器分配了四个组(也称四个区),即0~3组,每个组占用8个RAM单元,共占用片内RAM地址为00H~1FH的32个单元。各组的工作寄存器地址见表2-4。
表2-4 工作寄存器地址表
在任一时刻,CPU只能使用四组寄存器中的一组寄存器,并且把正在使用的那组寄存器称为当前寄存器组,其余的三组寄存器可用作一般RAM单元。至于到底是使用哪一组寄存器,由程序状态字寄存器PSW中的RS1、RS0的状态组合决定。CPU复位后,选中第0组工作寄存器为当前的工作寄存器组。
通用寄存器为CPU提供了就近存储数据的便利,有利于提高单片机的运算速度。此外,使用通用寄存器还能提高程序编制的灵活性,因此在单片机的应用编程中应充分地利用这些寄存器,以简化程序设计,提高程序运行速度。
(2)位寻址区。片内RAM的20H~2FH共有16个RAM单元,既可以作为一般的RAM单元使用,进行字节操作,也可以对单元中每一位共计128位进行位操作,因此把该区称为位寻址区,各位的位地址为00H~7FH。MCS-51单片机具有布尔处理机的功能,其指令系统中包括许多位操作指令,这些位操作指令可直接对这128位寻址,这个位寻址区可以构成布尔处理机的存储空间。表2-5为位寻址区的位地址表。
表2-5 片内RAM位寻址区的位地址表
这些可寻址位,通过执行指令可直接对某一位操作,如置1、清0或判1、判0等,可用作软件标志位或用于位(布尔)处理。这是一般微机和早期的单片机(如MCS-48单片机)所没有的,这种位寻址能力是MCS-51单片机的一个重要特点。
(3)用户RAM区。在片内RAM的低128字节单元中,通用寄存器占去了32个字节单元,位寻址区占去了16个字节单元,剩下的80个字节单元,是供用户使用的一般RAM区,其字节地址为30H~7FH。
对用户RAM区的使用没有任何规定和限制。在实际使用中,常把堆栈设置在RAM区。在编程中应特别注意,RAM单元不要和堆栈区单元冲突。
低128字节RAM的字节地址范围为00H~7FH,其中的位寻址区的位地址也为00H~7FH,89C51单片机采用不同的寻址方式来加以区分,即访问128个位地址的位寻址区用位寻址方式,访问低128字节单元用直接或间接寻址。这样就可区分开00H~7FH是位地址还是字节地址。
2.高128字节RAM
89C51单片机片内数据存储器高128字节单元是提供给特殊功能寄存器SFR使用的,其字节地址为80 H~FFH。特殊功能寄存器的总数为21个,其地址分散分布在80 H~FFH的地址空间中,只占用了高128字节单元中的很小一部分。
(1)特殊功能寄存器(SFR)。特殊功能寄存器SFR主要用于管理片内各功能部件,是一类特殊的寄存器。MCS-51单片机对特殊功能寄存器采取与片内RAM统一编址的方法进行管理,可以直接寻址,其中有些寄存器还可以进行位寻址。89C51共有21个特殊功能寄存器,现把其中部分寄存器简单介绍如下:
1)累加器ACC。累加器ACC为8位寄存器,是最常用的特殊功能寄存器,功能较多,地位重要。它既可用于存放操作数,也可用来存放运算的中间结果。89C51单片机中大部分单操作数指令的操作数就取自累加器,许多双操作数指令中的一个操作数也取自累加器。加、减、乘、除运算指令的运算结果都存放在累加器ACC或A、B寄存器对中。在指令系统中常用A作为累加器ACC的助记符。
2)B寄存器。B寄存器也是一个8位寄存器,主要用于乘、除运算。乘法运算时,B存放乘数,乘法操作后,乘积的高8位存于B中;除法运算时,B存放除数,除法操作后,余数存于B中。此外,在其他指令中,B寄存器也可以作为一般通用寄存器或一个RAM单元使用。
3)程序状态字PSW。程序状态字PSW是一个8位寄存器,用于存放程序运行中的各种状态信息,供程序查询或判别之用。其中有些位的状态是根据程序执行结果由硬件自动设置的,而有些位的状态则使用软件方法设定。PSW的位状态可以用专门指令进行测试,也可以用指令读出。一些条件转移指令将根据PSW某些位的状态进行程序转移。PSW各位的定义及其格式见表2-6。
表2-6 PSW程序状态字各位的含义及位地址
PSW除了有确定的字节地址(D0H)外,每一位均有位地址,见表2-6。除PSW.1位保留未用外,其余各位的定义及使用如下。
a.CY(PSW.7):进位/借位标志位(Carry)。CY是PSW中最常用的标志位。其功能有:①存放算术运算的进位(或借位)标志,在执行加法(或减法)运算指令时,如果运算结果的最高位有进位(或借位)时,CY由硬件置“1”,如果运算结果的最高位无进位(或借位)时,则CY由硬件清“0”;②在位操作中作位累加器使用。位传送、位与、位或等位操作中,进位标志位是固定的操作位之一。在指令中用C代替CY。
b.AC(PSW.6):半进位标志位,也称辅助进位标志位(Auxiliary Carry)。在执行加法(或减法)操作时,如果运算结果(和或差)的低半字节(位3)向高半字节(位4)有半进位(或半借位)时,则AC位将被硬件自动置“1”,否则AC位被自动清“0”。在BCD码调整中也要用到AC位状态。
c.F0(PSW.5):用户标志位(Flag)。这是一个供用户定义的标志位,用户可以根据自己的需要对F0位赋予一定的含义。用户需要利用软件方法置位或复位,以作为软件标志,用于控制程序的转向。
d.RS1和RS0(PSW.4、PSW.3):工作寄存器组选择位。用它们来选择CPU当前使用的工作寄存器组。工作寄存器共有四组,其对应关系见表2-7。
表2-7 工作寄存器组的选择
这两个选择位的状态是由软件设置的,被选中的寄存器组即为当前工作寄存器组。单片机上电复位后,RS1=RS0=0,CPU自动选择第0组为当前工作寄存器组。
用户根据需要可以利用传送指令对PSW整个字节操作或用位操作指令改变RS1和RS0的状态,以切换当前工作寄存器组。这样的设置为程序中保护现场提供了方便。
e.OV(PSW.2):溢出标志位(Over flow)。当进行带符号数的补码加/减运算或无符号数乘/除运算时,由硬件根据运算结果自动置“1”或复位。
在带符号数加/减运算中,OV=1表示加/减运算超出了累加器A所能表示的带符号数的有效范围(-128~+127),即产生了溢出,因此运算结果是错误的;否则,OV=0表示运算正确,即无溢出产生。
在乘法运算中,OV=1,表示乘积超过255,即乘积分别在B与A中;否则,OV=0,表示乘积只在A中。
在除法运算中,OV=1,表示除数为0,结果无效;否则,OV=0,结果有效。
f.PSW.1:保留位。89C51未用,89C52为F1用户标志位。
g.P(PSW.0):奇偶校验标志位(Parity)。执行完每条指令后,该位始终跟踪指示累加器A中“1”的个数。如果A中有奇数个“1”,则P置“1”,否则置“0”。凡是改变累加器A中内容的指令均会影响P标志位。
此标志位对串行通信中的数据传输有重要的意义。在串行通信中常采用奇偶校验的办法来校验数据传输的可靠性。
4)数据指针DPTR(Data Pointer)。数据指针DPTR为16位寄存器,它是MCS-51单片机中唯一的一个16位寄存器。编程时,DPTR既可以作为16位寄存器使用,也可以作为独立的两个8位寄存器分开使用,即DPH:DPTR高8位字节;DPL:DPTR低8位字节。
DPTR主要用于存放16位地址,通常在访问外部数据存储器时作间接寻址的地址指针使用。由于外部数据存储器的寻址范围为64KB,故把DPTR设计为16位。
5)堆栈指针SP(Stack Pointer)。堆栈指针SP是一个8位的特殊功能寄存器,它的内容指示出堆栈顶部在片内数据存储器中的位置。对于89C51来讲,堆栈指针SP的内容可指向片内00 H~7FH RAM的任何单元。系统复位后,堆栈指针SP初始化为07 H。
以下简述堆栈(Stack)的概念。
堆栈在计算机科学中,是一种特殊的链表形式的数据结构,所谓堆栈就是只允许在其一端(称为栈顶,英文为top)进行数据插入和数据删除操作的线性表。堆栈的最大特点是“后进先出LIFO(Last In First Out)”或“先进后出FILO(First In Last Out)”,先入栈的数据由于放在堆栈的底部,因而后出栈;而后入栈的数据存放在堆栈的顶部,因此先出栈。这和往弹仓压入子弹和从弹仓中弹出子弹的情形非常类似。这种数据结构方式对于处理中断、调用子程序都非常方便。
堆栈共有两种操作:一种叫数据入栈(PUSH);另一种叫数据出栈(POP)。在图2-15中,假如有8个RAM单元,每个单元都在其左面编有地址,堆栈由堆栈指针SP自动管理。每次进行压入或弹出操作以后,堆栈指针便自动调整以保持指示堆栈顶部的位置。
图2-15 堆栈的压入与弹出
在使用堆栈之前要先给SP赋值,以规定堆栈的起始位置,称为栈底。当一个数据入栈时,SP先自动加1,指出新的栈顶位置,然后数据入栈;反之,当一个数据出栈时,数据先出栈,然后SP自动减1,以指出当前栈顶位置。89C51的这种堆栈结构属于向上生长型的堆栈(另一种堆栈属于向下生长型)。
由于89C51单片机的堆栈设在片内RAM中,系统复位后,SP的内容为07 H,因此复位后堆栈实际上是从08H单元开始的。由于08H~1FH单元分别属于工作寄存器1~3区,如果程序要用到这些区,就应该先修改SP值,在片内RAM的30H~7FH单元中另外开辟堆栈。SP的内容一经确定,堆栈的位置即可确定。
6)I/O端口P0~P3。P0~P3为四个8位特殊功能寄存器,分别是四个并行I/O端口的锁存器。它们都有字节地址,每一个端口锁存器还有位地址,所以,每一条I/O线均可独立用作输入或输出。用作输出时,可以锁存数据;用作输入时,数据可以缓冲。
在MCS-51单片机中,I/O和RAM统一编址,既可以字节寻址,也可以位寻址,使用起来较方便。有关P0~P3的详细情况,在本章第三节中详细介绍。
7)串行数据缓冲器SBUF。串行数据缓冲器SBUF用于存放要发送或已接收的数据。它实际上是由两个独立的寄存器组成,一个是发送缓冲器;另一个是接收缓冲器。当要发送的数据传送到SBUF时,进入的是发送缓冲器;当要从SBUF取数据时,则取自接收缓冲器,取走的是刚接收到的数据。
8)定时/计数器。89C51中有两个16位定时/计数器T0和T1。它们分别由两个独立的8位寄存器组成,共有四个独立的寄存器:TH0、TL0、TH1、TL1。在使用过程中可以对这四个寄存器进行寻址,但不能把T0和T1当成16位寄存器来访问。
9)其他控制寄存器。TCON、TMOD、IE、IP、SCON和PCON寄存器分别包含有中断系统、定时/计数器、串行口和供电方式的控制及状态位,这些寄存器将在后续章节中陆续介绍。
(2)特殊功能寄存器中的字节寻址和位寻址。89C51有21个可寻址的特殊功能寄存器,其中有11个特殊功能寄存器是可以位寻址的。各寄存器的字节地址、位符号及位地址列于表2-8中。
对特殊功能寄存器的字节寻址问题作如下几点说明:
1)21个可字节寻址的特殊功能寄存器是不连续地分散在片内RAM高128字节单元之中,尽管还余有许多空闲地址,但用户并不能使用。
2)对于只能使用直接寻址方式的特殊功能寄存器,书写时既可以使用它们的符号名(如:指令“MOV A,P1”中的P1),也可以使用它们的字节地址(如:指令“MOV A,90H”中的90 H)。
特殊功能寄存器中全部可位寻址的位共有83位,这些位都具有专门的定义和用途。这样,加上位寻址的128位,在89C51单片机的片内RAM中共有128+83=211个可寻址位。
除了上述21个特殊功能寄存器SFR以外,还有一个16位的PC(Program Counter),称为程序计数器。PC没有地址,不占据RAM字节单元,在物理上是独立的,因此是不可寻址的寄存器。用户无法对它直接进行读写操作,但可以通过转移、调用、返回等指令改变其内容,以实现程序的转移。PC的作用是控制程序的执行顺序,其内容为下一条要执行指令的地址,寻址范围达64 KB。PC有自动加1的功能,从而可以实现程序的顺序执行。因其地址不在特殊功能寄存器SFR之内,一般不计作特殊功能寄存器。
表2-8 特殊功能寄存器地址表
* SFR既可按位寻址,也可直接按字节寻址。