《例说51单片机(C语言版)(第3版)》一1.3 认识MCS-51的存储器结构

简介:

本节书摘来自异步社区《例说51单片机(C语言版)(第3版)》一书中的第1章,第1.3节,作者 张义和 , 王敏男 , 许宏昌 , 余春长,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.3 认识MCS-51的存储器结构

例说51单片机(C语言版)(第3版)
除了无ROM型的8031及8032外,MCS-51的存储器包括程序存储器(ROM)与数据存储器(RAM)两部分,一般地这两部分是独立的个体。标准的8x51系列具有4KB程序存储器、128B数据存储器,而标准的8x52系列具有8KB、256B数据存储器,刚好是8x51系列的两倍。不管是8x51、8031、8032或8x52,其外部扩展的程序存储器或数据存储器最多为64KB。

虽然MCS-51的兼容单片机都扩展了其内部程序存储器与数据存储器,例如Atmel半导体公司的TS83C51RB2,其内部有16KB程序存储器、256B数据存储器;TS83C51RC2,其内部有32KB程序存储器、256B数据存储器;TS83C51RD2,其内部有64KB程序存储器、768KB数据存储器。尽管如此,在此仍探讨MCS-51单片机微控制器的标准存储器结构。

1.3.1 程序存储器

顾名思义,程序存储器(ROM)是存放程序的位置,而CPU将自动从程序存储器中读取所要执行的指令码。MCS-51可选择使用内部程序存储器或外部程序存储器(如图1-18所示),说明如下。

image若使用8031或8032,由于内部没有程序存储器,一定要使用外部程序存储器,所以其overline {{text{EA}}} 引脚必须接地。

image当overline {{text{EA}}} 引脚接高电平时,CPU将使用内部程序存储器,若程序超过4KB(8x51)或8KB(8x52)时,CPU会自动从外部程序存储器里,读取超过部分的程序代码。

image当overline {{text{EA}}} 引脚接地时,CPU将自外部程序存储器读取所要执行的指令码,而CPU内部的程序存储器形同虚设。

说明:

4KB的程序存储器对于初学者而言,已是绰绰有余。坏掉的8x51/8x52,很可能是其中的程序存储器坏掉,可将其overline {{text{EA}}}引脚接地,改为外接程序存储器,即可当作8031/8032使用。
当CPU复位后,程序将从程序存储器0000H地址位置开始执行,如没有遇到跳转指令,则按程序存储器地址顺序执行。当然,程序存储器前面几个位置还有一些玄机,留待中断的单元再详细说明。


7c6e64076d5ba81e997116ed27909d2c213d8274

图1-18 MCS-51的程序存储器结构

1.3.2 数据存储器

MCS-51的程序存储器与数据存储器是分开的独立区块,所以存取数据存储器时,所使用的地址并不会与程序存储器冲突。相对于程序存储器而言,数据存储器就不那么简单,如图1-19所示。


7bd77fd17068e6a1b733be2a9348d06bae396925

图1-19 MCS-51的数据存储器结构

除了内部数据存储器外,8x51的数据存储器还可扩展外部数据存储器,这两部分的数据存储器可以并存。不过,存取数据存储器时,所采用的指令并不一样,例如,存取内部数据存储器时,可用MOV指令,但存取外部数据存储器时,则使用MOVX指令。

另外,内部数据存储器中,从0000H到007FH之间的128B为可直接寻址或间接寻址的存储器。在编写C语言程序时,以数据类型来区别直接寻址与间接寻址。在这一区间的数据存储器又可分成三部分(如图1-20所示),说明如下。

1.寄存器组区

0000H到001FH的32个地址为寄存器组(Register Bank)区,说明如下。

(1)0000H到0007H为寄存器组0(即RB0),0008H到000FH为寄存器组1(即RB1),0010H到0017H为寄存器组2(即RB2),0018H到001FH为寄存器组3(即RB3)。


ce29d67e97027def549ceac326374bc70a7af65c

图1-20 内部数据存储器

(2)每组寄存器组都包含R0~R7共8个寄存器,而任一时刻只能使用其中一组寄存 器组。

(3)寄存器组的切换可以用程序状态字寄存器(Program Status Word,PSW)中的RS1与RS0来决定,如表1-4所示。


ff5a964675337c92b618720a6013237e1435d5a2

(4)当CPU复位时,系统的堆栈指针(SP)指向07H地址,所以数据存入堆栈时,将从08H开始,也就是RB1里的R0地址。为避免冲突或不必要的错误,通常会把堆栈指针移到30H以后的地址。

2.可位寻址区

0020H到002FH的16个字节存储器区为可位寻址区。通常存取存储器是以字节为单位,“可位寻址”则是指定存取1个位(bit)。在8051的汇编语言里,可使用布尔运算指令进行位操作,例如,要把20H存储器地址的bit 5设置为1,则可使用下列指令:

SETB      20H.5
AI 代码解读

另外,从0020H到002FH的16个字节总共128个位(16×8),也可以直接指定为0到127,以刚才的20H存储器地址的bit 5而言,也可将“20H.5”指定为“05”,指令如下:

SETB      05
AI 代码解读

同理,若要将25H存储器地址的bit 2清除为0,则可使用下列指令:

CLR       25H.2
AI 代码解读

CLR     42
AI 代码解读

其中,42=58+2。

3.一般数据与堆栈区

0030H到007FH的80个字节地址为一般数据存取及堆栈区。由于CPU复位后,堆栈指针指向07H位置,为了确保数据的安全与程序执行的正确,如果在程序之中使用了PUSH、POP命令,最好能把堆栈指针改至本区,例如,要将堆栈指针移至0030H地址,则在程序开始处即使用如下命令:

MOV         SP, #30H
AI 代码解读

从0080H到00FFH之间的128B为特殊功能寄存器(Special Function Register,SFR)或可直接寻址的存储器,至于“特殊功能寄存器”,稍后再详细说明。

如果是8052/8032,则0080H到00FFH之间的128B除了是特殊功能寄存器或可直接寻址的存储器外,另外也可以使用间接寻址的方式存取与这特殊功能寄存器位置重叠但为独立的存储器。

1.3.3 特殊功能寄存器

在MCS-51里,寄存器只是CPU里特定地址的数据存储器而已。而在0080H到00FFH之间的128B,正是特殊功能寄存器(Special Function Register,SFR)所在位置。特殊功能寄存器就是8x51/52内部的结构,若以汇编语言编写程序时,必须熟练掌握这些寄存器,若以C语言编写程序,就不是那么重要。其位置的声明放置在Keil C所提供的“reg51.h”头文件(详见后面章节)里,只要把它包含到程序里即可,而不必记忆这些位置。以下简单介绍这些寄存器(如表1-5所示),仅供参考。


e05d097fa9255cf3ce5166db4131bee389f09170

注:(1)本表C8-CF行部分为8052/8032才有的寄存器,本表第1列的部分为可位寻址的寄存器,较深灰底的部分为89S51/52才有的。

(2)8051/52、89C51/52只有一组数据指针寄存器,所以其中的DP0L应改为DPL,DP0H应改为DPH。

imageP0、P1、P2、P3
P0~P3为MCS-51的4个输入/输出端口,其地址分别为80H、90H、0A0H及0B0H,待第3章再详细介绍。

imageSP
SP为堆栈指针寄存器(Stack Pointer register),其地址为81H。堆栈是一种特殊的数据存储方式,其数据的操作顺序是先进后出(First In Last Out,FILO),当数据以PUSH命令送入堆栈时,SP自动减1;若以POP命令从堆栈取出数据时,SP自动加1。

imageDPL、DPH
89C51只有一组16位的数据指针寄存器(Data Pointer register,DPTR),这组数据指针寄存器是由DPL与DPH两个8位的数据指针寄存器组成,其地址分别为82H、83H。若以DPL为低8位、DPH为高8位,所组成的16位数据指针寄存器将可寻址到64KB的数据地址。89S51有两组16位数据指针寄存器,分别是DP0L、DP0H、DP1L及DP1H,其地址分别为82H、83H、84H、85H。若以汇编语言编写程序时,DPTR是查表法的必备寄存器。不过,使用C语言编写程序时,就不太需要由我们直接控制这个寄存器。

imagePCON
PCON为电源控制寄存器(Power Control register),其地址为87H,其功能是设置CPU的电源方式,待后续7-3-3节再行说明。

imageTCON
TCON为定时器/计数器控制寄存器(Timer/Counter Control register),其地址为88H,其功能是设置定时器/计数器的启动,记录定时/计数溢出及外部中断的类型等(见第6章),待后续关于定时器/计数器部分(第7章),再行说明。

imageTMOD
TMOD为定时器/计数器方式控制寄存器(Timer/Counter Mode Control register),其地址为089H,其功能是设置定时/计数的方式,待后续关于定时器/计数器部分(第7章)再行说明。

imageTL0、TL1、TH0、TH1
TL0、TH0为第一组定时器/计数器(Timer0)的计数器,其地址为8AH、8CH,将TH0与TL0组合即可进行16位的定时/计数。TL1、TH1为第二组定时器/计数器(Timer1)的计数器,其地址为8BH、8DH,将TH1与TL1组合即可进行16位的定时/计数,待后续关于定时器/计数器部分(第7章)再行说明。
image SCON
SCON为串行口控制寄存器(Serial port Control register),其地址为98H,其功能是设置串行口工作方式与标志,待后续关于串行口部分(第8章)再行说明。

imageSBUF
SBUF为串行口缓冲器(Serial BUFfer),其地址为99H,它由使用同一个地址的两个寄存器所构成,其中一个寄存器作为发送数据用的缓冲器,另一个寄存器作为接收数据用的缓冲器。至于如何分辨同一个地址的两个寄存器,视指令而定,若是数据发送的指令,则自动定位到发送数据用的缓冲器;若是接收数据的指令,则自动定位到接收数据用的缓冲器,待后续关于串行口部分(第8章)再行说明。

imageIE
IE为中断使能寄存器(Interrupt Enable register),其地址为0A8H,其功能是启用中断功能,待后续关于中断部分(第6章)再行说明。

imageIP
IP为中断优先等级寄存器(Interrupt Priority register),其地址为0B8H,其功能是设置中断的优先等级,待后续关于中断部分(第6章)再行说明。

imageT2CON
T2CON为Timer2的定时器/计数器控制寄存器,其地址为0C8H,其功能是设置Timer2的启动、记录定时/计数溢出,以及外部中断的类型等,而Timer2只在8052/8032中才有。

imageRCAP2L、RCAP2H
RCAP2L、RCAP2H为捕捉寄存器(Capture register),其地址为0CAH、0CBH。当Timer2在捕捉方式时,若T2EX(P1.1)引脚上的输入信号由高电平跳变为低电平,TL2与TH2的内容将被载入RCAP2L与RCAP2H里,就像是把Timer2的内容“捉进”RCAP寄存器一样。

image TL2、TH2
TL2、TH2为第三组定时器/计数器(Timer2)的计数器,其地址为0CCH、0CDH,将TH2与TL2组合即可进行16位的定时/计数。

imagePSW
PSW为CPU的程序状态字组寄存器(Program Status Word register),其地址为0D0H,其内容说明如下。


31686e28df2568161f1c0acb0cb95920a0e6ea74

PSW.7:本位为进位标志(CY),进行加法(减法)运算时,若最左边位(MSB,即bit 7)产生进位(借位)时,则本位将自动设置为1,即CY=1;否则CY=0。
PSW.6:本位为辅助进位标志(AC),进行加法(减法)运算时,若bit 3产生进位(借位)时,则本位将自动设置为1,即AC=1;否则AC=0。
PSW.5:本位为用户标志(F0),可由用户自行设置的位。
PSW.4与PSW.3:这两个位为寄存器组选择位(RS1、RS0),其功能如表1-4所示。
PSW.2:本位为溢出标志(OV),当进行算术运算时,若发生溢出,则OV=1;否则 OV=0。
PSW.1:本位为保留位,没有提供服务。
PSW.0:本位为校验标志(P),8051采用偶校验,若ACC里有奇数个1,则P=1;若ACC里有偶数个1,则P=0。
imageACC
ACC累加器(Accumulator)又称为A寄存器,其地址为0E0H,这个寄存器提供CPU主要运行的位置,可说是最常用的寄存器。

image B
B寄存器的地址为0F0H,主要功能是配合A寄存器进行乘法或除法运算,进行乘法运算时,乘数放在B寄存器,而运算结果的高8位放在B寄存器;进行除法运算时,除数放在B寄存器,而运算结果的余数放在B寄存器。若不进行乘/除法运算,B寄存器也可当成一般寄存器使用。

image AUXR
AUXR寄存器为89S51新增的辅助寄存器(AUXiliary Register),其地址为8EH,其内容说明如下。


cae06117550591e72384fa670914c7d94d39ac72

WDIDLE:本位设置在待机方式(Idle Mode)下,是否启用看门狗。若本位设置为1,则在Idle方式下将启用看门狗;若本位设置为0,则在Idle方式下将停用看门狗。
DISRTO:本位设置是否输出复位信号,若本位设置为1,则Reset引脚(第9脚)只有输入功能;若本位设置为0,则在WDT计数完毕后,Reset引脚输出复位信号(即高电平脉冲)。
DISALE:本位设置是否启用ALE信号,若本位设置为1,则只有在执行MOVX指令或MOVC指令时,ALE引脚(第30脚)才会正常工作;若本位设置为0,则固定每6个脉冲就输出1个高电平脉冲,稍后说明。
其他位为保留位。当然,这个寄存器只有在89S51里才有作用。

imageAUXR1
AUXR1寄存器为89S51新增的第2个辅助寄存器,其地址为0A2H,其内容说明如下:


0cab74b61a31bf3ad71ca415be21b838b95473a6

DPS:本位的功能是选择数据指针寄存器。若本位设置为1,则使用DP1L及DP1H;若本位设置为0,则使用DP0L及DP0H。
其他位为保留位。同样,这个寄存器只有在89S51里才有作用。

imageWDTRST
WDTRST寄存器为89S51新增的看门狗定时器复位寄存器(WatchdogTimer Reset register),其地址为0A6H。当要启用看门狗定时器WDT时,依序将01EH、0E1H放入WDTRST寄存器,当14位计数器溢出(达到16383,即3FFFH),即由RESET引脚送出一个高电平脉冲以复位系统。此脉冲的宽度为98 times T_text{OSC},其中T_text{OSC} = 1/F_text{OSC} ,以12MHz的时钟脉冲为例,脉冲的宽度为98 times frac{1}{{12 times 10^6 }} cong 8.167mtext{u} s,关于看门狗与节电方式,待后续相关单元,再行说明。

相关文章
【C语言】结构体内存对齐:热门面试话题
【C语言】结构体内存对齐:热门面试话题
202 0
【C语言程序设计——选择结构程序设计】预测你的身高(头歌实践教学平台习题)【合集】
分支的语句,这可能不是预期的行为,这种现象被称为“case穿透”,在某些特定情况下可以利用这一特性来简化代码,但在大多数情况下,需要谨慎使用。编写一个程序,该程序需输入个人数据,进而预测其成年后的身高。根据提示,在右侧编辑器补充代码,计算并输出最终预测的身高。分支下的语句,提示用户输入无效。常量的值必须是唯一的,且在同一个。语句的作用至关重要,如果遗漏。开始你的任务吧,祝你成功!,程序将会继续执行下一个。常量都不匹配,就会执行。来确保程序的正确性。
176 10
|
3月前
|
【C语言程序设计——基础】顺序结构程序设计(头歌实践教学平台习题)【合集】
目录 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果: 任务描述 相关知识 编程编写一个程序,从键盘输入3个变量的值,例如a=5,b=6,c=7,然后将3个变量的值进行交换,使得a=6,b=7,c=5。面积=sqrt(s(s−a)(s−b)(s−c)),s=(a+b+c)/2。使用输入函数获取半径,格式指示符与数据类型一致,实验一下,不一致会如何。根据提示,在右侧编辑器补充代码,计算并输出圆的周长和面积。
100 10
【C语言程序设计——选择结构程序设计】求一元二次方程的根(头歌实践教学平台习题)【合集】
本任务要求根据求根公式计算并输出一元二次方程的两个实根,精确到小数点后两位。若方程无实根,则输出提示信息。主要内容包括: - **任务描述**:使用求根公式计算一元二次方程的实根。 - **相关知识**:掌握 `sqrt()` 函数的基本使用方法,判断方程是否有实根。 - **编程要求**:根据输入的系数,计算并输出方程的根或提示无实根。 - **测试说明**:提供两组测试数据及预期输出,确保代码正确性。 - **通关代码**:包含完整的 C 语言代码示例,实现上述功能。 通过本任务,你将学会如何处理一元二次方程的求解问题,并熟悉 `sqrt()` 函数的使用。
71 5
【C语言程序设计——选择结构程序设计】按从小到大排序三个数(头歌实践教学平台习题)【合集】
本任务要求从键盘输入三个数,并按从小到大的顺序排序后输出。主要内容包括: - **任务描述**:实现三个数的排序并输出。 - **编程要求**:根据提示在编辑器中补充代码。 - **相关知识**: - 选择结构(if、if-else、switch) - 主要语句类型(条件语句) - 比较操作与交换操作 - **测试说明**:提供两组测试数据及预期输出。 - **通关代码**:完整代码示例。 - **测试结果**:展示测试通过的结果。 通过本任务,你将掌握基本的选择结构和排序算法的应用。祝你成功!
72 4
【C语言程序设计——选择结构程序设计】求阶跃函数的值(头歌实践教学平台习题)【合集】
本任务要求输入x的值,计算并输出特定阶跃函数的结果。主要内容包括: 1. **选择结构基本概念**:介绍if、if-else、switch语句。 2. **主要语句类型**:详细解释if、if-else、switch语句的使用方法。 3. **跃迁函数中变量的取值范围**:说明如何根据条件判断变量范围。 4. **计算阶跃函数的值**:通过示例展示如何根据给定条件计算函数值。 编程要求:在右侧编辑器Begin-End之间补充代码,实现阶跃函数的计算和输出。测试说明提供了多个输入及其预期输出,确保代码正确性。最后提供通关代码和测试结果,帮助理解整个过程。
68 0
【C语言程序设计——选择结构程序设计】判断一个数是不是5和7的倍数(头歌实践教学平台习题)【合集】
本任务要求输入一个正整数,判断其是否同时是5和7的倍数,若是输出"Yes",否则输出"No"。内容涵盖选择结构的基本概念、主要语句类型(if、if-else、switch)及条件判断逻辑,帮助理解编程中的分支执行与条件表达式。测试用例包括正数、负数及非倍数情况,确保代码逻辑严谨。通关代码示例如下: ```cpp #include "stdio.h" int main(){ int a; scanf("%d", &a); if (a <= 0){ printf(&quo
187 0
【C语言程序设计——选择结构程序设计】求输入的日期是该年的第几天(头歌实践教学平台习题)【合集】
本任务要求编写程序,根据用户输入的年月日(以空格或回车分隔),计算并输出该天是该年的第几天,需注意判断闰年。主要内容包括: 1. **任务描述**:实现从键盘输入年月日,计算该天是当年的第几天。 2. **相关知识**: - `switch` 结构的基本语法及使用注意事项。 - 判断闰年的条件:能被4整除但不能被100整除,或能被400整除的年份为闰年。 3. **编程要求**:根据提示补充代码,确保程序正确处理输入并输出结果。 4. **测试说 示例代码展示了如何使用 `switch` 语句和闰年判断逻辑来完成任务。通过此练习,掌握 `switch` 语句的应用及闰年判断方法。
113 0
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
235 16
|
10月前
|
【C语言基础篇】结构控制(中)循环结构
【C语言基础篇】结构控制(中)循环结构
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等