RAM(数据存储器)存放数据(常量或变量)或运算的结果,相当于计算机的内存;
8051单片机内部有256字节的数据存储器,如果内部数据存储器不够用,可以外接数据存储器。8051单片机最大可以外接容量为64KB的数据存储器(RAM),它与片内256字节数据存储器分开编址,如下图所示。
当8051单片机连接片外RAM时,片内RAM的00H~FFH存储单元地址与片外RAM的0000H~00FFH存储单元地址相同,为了区分两者,在用汇编语言编程时,读写片外RAM时要用“MOVX”指令(读写片内RAM时要用“MOV”指令),在用C语言编程时,读写RAM时须先声明数据类型(内部数据或外部数据),若读写的数据存放在片内RAM中,要声明数据类型为内部数据类型(如用“data”声明)。
若读写的数据存放在片外RAM中,应声明数据类型为外部数据类型(如用“xdata”声明),单片机会根据声明的数据类型自动选择读写片内或片外RAM。
8051单片机内部有128字节的数据存储器(地址为00H~7FH)和128字节的特殊功能寄存器区(地址为80H~FFH),如下图所示。根据功能不同,8051单片机的数据存储器可分为工作寄存器区(0~3组)(32 Bytes)、位寻址区(16 Bytes)、用户RAM区(80 Bytes)、特殊功能寄存器区(128 bytes)。
单片机在工作时需要处理很多数据,有些数据要用来运算,有些要反复调用,有些要用来比较校验等,在处理这些数据时需要有地方能暂时存放这些数据,单片机提供暂存数据的地方就是工作寄存器。
8051单片机的工作寄存器区总存储空间为32字节,由0~3组工作寄存器组成,每组有8个工作寄存器(R0~R7),共32个工作寄存器(存储单元),地址编号为00H~1FH,每个工作寄存器可存储一个字节数据(8位),四组工作寄存器的各个寄存器地址编号如下:
单片机上电复位后,默认使用第0组工作寄存器,可以通过编程设置PSW(程序状态字寄存器)的RS1、RS0位的值来换成其他组工作寄存器。
当PSW的RS1位=0、RS0位=0时,使用第0组工作寄存器,RS1位=0、RS0位=1时使用第1组工作寄存器,RS1位=1、RS0位=0时使用第2组工作寄存器,RS1位=1、RS0位=1时使用第3组工作寄存器,如下图所示。不使用的工作寄存器可当作一般的数据存储器使用。
3.2.2 位寻址区
位寻址区位于工作寄存器区之后,总存储空间为16字节,有16个字节存储单元,字节地址为20H~2FH,每个字节存储单元有8个存储位,一共有16×8=128个存储位,每个位都有地址,称为位地址,利用位地址可以直接对位进行读写。
位寻址区的16个字节单元与128个位的地址编号如下图所示,从图中可以看出,字节单元和存储位有部分相同的地址编号,单片机是以指令类型来区分访问地址为字节单元还是位单元,比如用字节指令访问地址20H时,访问的为20H字节单元,可以同时操作该字节单元的8位数,用位指令访问地址20H时,访问的为24H字节单元的D0位,只能操作该位的数据。
用户RAM区又称为数据缓存区,8051单片机的用户RAM区有80个存储单元(字节),地址编号为30H~7FH,用户RAM区一般用来存储随机数据和运算中间结果等。
特殊功能寄存器简称SFR(Special Function Register),主要用于管理单片机内部各功能部件(如定时器/计数器、I/O 端口、中断控制器和串行通信口等),通过编程设定一些特殊功能寄存器的值,可以让相对应的功能部件进入设定的工作状态。
1.特殊功能寄存器的符号、字节地址、位地址和复位值
8051单片机有21个特殊功能寄存器(SFR),见下表1,每个特殊功能寄存器都是一个字节单元(有8位),它们的地址离散分布在80H~FFH 范围内,51单片机规定特殊寄存器只能用直接寻址(直接写出 SFR 的地址或符号)方式访问。
21个特殊功能寄存器都能以字节为单位进行访问,其中有一些特殊功能寄存器还可以进行位访问,能访问的位都有符号和位地址,位地址为特殊功能寄存器的字节地址加位号。以特殊功能寄存器P0为例,其字节地址为80H(字节地址值可以被8整除),其P0.0~P0.7位的位地址为80H~87H,访问字节地址80H时可读写8位(P0.0~P0.7位),访问位地址82H时仅可读写P0.2位。
有位地址的特殊寄存器既可以用字节地址访问整个寄存器(8位),也可以用位地址(或位符号)访问寄存器的某个位,无位地址的特殊寄存器只能用字节地址访问整个寄存器。当位地址和字节地址相同时,单片机会根据指令类型来确定该地址的类型。单片机上电复位后,各特殊功能寄存器都有个复位初始值,具体见表1,x表示数值不定(或1或0)。
表1 8051单片机的21个特殊功能寄存器(SFR)
2.部分特殊功能寄存器介绍
单片机的特殊功能寄存器很多,可以分为特定功能型和通用型。对于特定功能型特殊功能寄存器,当往某些位写入不同的值,可以将其控制的功能部件设为不同工作方式,读取某些位的值,可以了解相应功能部件的工作状态;通用型特殊功能寄存器主要用于运算、寻址和反映运算结果状态。
下面介绍一些通用型特殊功能寄存器。
累加器又称ACC,简称A,是一个8位寄存器,其字节地址为E0H。累加器是单片机中使用最频繁的寄存器,在进行算术或逻辑运算时,数据大多数先进入ACC,运算完成后,结果大多数也送入ACC。
寄存器B主要用于乘、除运算,其字节地址是F0H。在乘法运算时,一个数存放在A(累加器)中,另一个数存放在B中,运算结果得到的积(16位)的高字节存放在B中,低字节存放在A中;在除法运算时,被除数存取自A,除数取自B,运算结果得到商(8位)和余数(8位),商存放在A中,余数存放在B中。
数据指针寄存器(DPTR)简称数据指针,是一个16位寄存器,由DPH和DPL两个8位寄存器组成,地址分别为83H、82H。DPTR主要在单片机访问片外RAM时使用,用于存放片外RAM的16位地址,DPH保存高8位地址,DPL保存低8位地址。
人们在洗碗碟时,通常是将洗完的碗碟一只一只由下往上堆起来,使用时则是将碗碟从上往下一只一只取走。这个过程有两个要点:一是这些碗碟的堆放是连续的;二是先堆放的后取走,后堆放的先取走。
单片机的堆栈与上述情况类似。堆栈是指在单片机数据存储器中划分出的一个连续的存储空间,这个存储空间存取数据时具有“先进后出,后进先出”的特点。
在存储器存取数据时,首先根据地址选中某个单元,再将数据存入或取出。如果有一批数据要连续存入存储器,比如将5个数据(每个数据为8位)依次存入地址为30H~34H的5个存储单元中,按一般的操作方法是:先选中地址为30H的存储单元,再将第1个数据存入该单元,然后选中地址为31H的存储单元,再将第2个数据存入该单元……显然这样存取数据比较麻烦,采用堆栈可以很好地解决这个问题。
在数据存储器中划分堆栈的方法是:通过编程的方法设置堆栈指针寄存器(SP)的值,如让SP=2FH,SP就将存储器地址为2FH的存储单元设为堆栈的栈顶地址,2FH单元后面的连续存储单元就构成了堆栈,如下图所示。堆栈设置好后,就可以将数据按顺序依次存入堆栈或从堆栈中取出,在堆栈中存取数据按照“先进后出,后进先出”的规则进行。
需要注意的是,堆栈指针寄存器(SP)中的值并不是堆栈的第一个存储单元的地址,而是前一个单元的地址,例如SP=2FH,那么堆栈的第一个存储单元的地址是30H,第1个数据存入30H单元。单片机通电复位后,SP的初始值为07H,这样堆栈第一个存储单元的地址就为08H,由于08H~1FH地址已划分给1~3组工作寄存器,在需要用到堆栈时,通常在编程时设SP=2FH,这样就将堆栈设置在数据存储器的用户RAM区(30H~7FH)。
程序状态字寄存器(PSW)的地址是 D0H,它是一个状态指示寄存器(又称标志寄存器),用来指示系统的工作状态。PSW是一个8位寄存器,可以存储8位数,各位代表不同的功能。程序状态字寄存器(PSW)的字节地址、各位地址和各位功能如下图所示。
D7位(C):进位标志位。当单片机进行加、减运算时,若运算结果最高位有进位或借位时,C位置1,无进位或借位时,C位置0。在进行位操作时,C用作位操作累加器。
D6位(AC):半进位标志位。单片机进行加、减运算时,当低半字节的D3位向高半字节的D4位有进位或借位时,AC位置1,否则AC位置0。
D5位(F0):用户标志位0。用户可设定的标志位,可置1或置0。
D4位(RS1)、D3位(RS0):工作寄存器组选择位。这两位有4种组合状态,用来控制工作寄存器区(00H~1FH)4组中的某一组寄存器进入工作状态。
D2位(OV):溢出标志位。在进行有符号数运算时,若运算结果超出−128~+127范围,OV=1,否则OV=0;当进行无符号数乘法运算时,若运算结果超出255,OV=1,否则OV=0;当进行无符号数除法运算时,若除数为0,OV=1,否则OV=0。
D1位(F1):用户标志位1。同F0位,用户可设定的标志位,可置1或置0。
D0位(P):奇偶校验位。该位用于对累加器A中的数据进行奇偶校验,当累加器A中“1”的个数为奇数值时,P=1,若累加器A中的“1”的个数为偶数值时,P=0。51系列单片机总是保持累加器A与P中“1”的总个数为偶数值,比如累加器A中有3个“1”,即“1”的个数为奇数值,那么 P 应为“1”,这样才能让两者“1”的总个数为偶数值,这种校验方式称作偶校验。