《例说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所示),说明如下。

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

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

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

说明:

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

e46e59f684b744fa6f70e7dd5bba66ce2f5b97d4

1-3-2 数据存储器

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

43717e123d22718e9c02856d2f147be84ab26db3

除了内部数据存储器外,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)。

fe7279e6e5feb26c3d8e1e7ceaf37773b4e2a8c0

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

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

c29f8bb8b6a15460e297fa84c64039384ac5d579

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

2.可位寻址区

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

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

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

CLR       25H.2```
或

CLR 42`
其中,42=58+2。

3.一般数据与堆栈区

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

MOV         SP, #30H```
从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所示),仅供参考。

<div style="text-align: center"><img src="https://yqfile.alicdn.com/9df418014608fbd4ae2fe0eeda9adc5369e19e36.png" width="" height="">
</div>

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

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

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

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

圓 DPL、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语言编写程序时,就不太需要由我们直接控制这个寄存器。

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

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

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

圓 TL0、TL1、TH0、TH1
TL0、TH0为第一组定时器/计数器(Timer0)的计数器,其地址为8AH、8CH,将TH0与TL0组合即可进行16位的定时/计数。TL1、TH1为第二组定时器/计数器(Timer1)的计数器,其地址为8BH、8DH,将TH1与TL1组合即可进行16位的定时/计数,待后续关于定时器/计数器部分(第7章)再行说明。

圓 SCON
SCON为串行口控制寄存器(Serial port Control register),其地址为98H,其功能是设置串行口工作方式与标志,待后续关于串行口部分(第8章)再行说明。

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

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

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

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

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

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

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


<div style="text-align: center"><img src="https://yqfile.alicdn.com/25e3c8f6f7ade2825cc500fa13ade337376dbf3c.png" width="" height="">
</div>

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。
圓 ACC
ACC累加器(Accumulator)又称为A寄存器,其地址为0E0H,这个寄存器提供CPU主要运行的位置,可说是最常用的寄存器。

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

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


<div style="text-align: center"><img src="https://yqfile.alicdn.com/dfe6a980baf1aa7c19a65e8c81d30c6e52bf7dcc.png" width="" height="">
</div>

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里才有作用。

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


<div style="text-align: center"><img src="https://yqfile.alicdn.com/16956fb531f9dfac8d70c93782cf74b15a5d5134.png" width="" height="">
</div>

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

圓 WDTRST
相关文章
|
1月前
|
网络协议 编译器 Linux
【C语言】结构体内存对齐:热门面试话题
【C语言】结构体内存对齐:热门面试话题
|
7天前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
47 16
|
5月前
|
C语言
【C语言基础篇】结构控制(中)循环结构
【C语言基础篇】结构控制(中)循环结构
|
26天前
|
C语言
【总结】单片机重点知识总结记录之C语言条件编译(五)
【总结】单片机重点知识总结记录之C语言条件编译(五)
|
29天前
|
编译器 C语言 Python
C语言结构
C语言结构
14 0
|
2月前
|
存储 编译器 程序员
C语言程序的基本结构
C语言程序的基本结构包括:1)预处理指令,如 `#include` 和 `#define`;2)主函数 `main()`,程序从这里开始执行;3)函数声明与定义,执行特定任务的代码块;4)变量声明与初始化,用于存储数据;5)语句和表达式,构成程序基本执行单位;6)注释,解释代码功能。示例代码展示了这些组成部分的应用。
88 10
|
2月前
|
C语言
C语言程序设计核心详解 第四章&&第五章 选择结构程序设计&&循环结构程序设计
本章节介绍了C语言中的选择结构,包括关系表达式、逻辑表达式及其运算符的优先级,并通过示例详细解释了 `if` 语句的不同形式和 `switch` 语句的使用方法。此外,还概述了循环结构,包括 `while`、`do-while` 和 `for` 循环,并解释了 `break` 和 `continue` 控制语句的功能。最后,提供了两道例题以加深理解。
|
2月前
|
存储 算法 C语言
数据结构基础详解(C语言): 二叉树的遍历_线索二叉树_树的存储结构_树与森林详解
本文从二叉树遍历入手,详细介绍了先序、中序和后序遍历方法,并探讨了如何构建二叉树及线索二叉树的概念。接着,文章讲解了树和森林的存储结构,特别是如何将树与森林转换为二叉树形式,以便利用二叉树的遍历方法。最后,讨论了树和森林的遍历算法,包括先根、后根和层次遍历。通过这些内容,读者可以全面了解二叉树及其相关概念。
|
2月前
|
C语言
C语言程序设计核心详解 第三章:顺序结构,printf(),scanf()详解
本章介绍顺序结构的基本框架及C语言的标准输入输出。程序从`main()`开始依次执行,框架包括输入、计算和输出三部分。重点讲解了`printf()`与`scanf()`函数:`printf()`用于格式化输出,支持多种占位符;`scanf()`用于格式化输入,需注意普通字符与占位符的区别。此外还介绍了`putchar()`和`getchar()`函数,分别用于输出和接收单个字符。
|
2月前
|
存储 机器学习/深度学习 C语言
数据结构基础详解(C语言): 树与二叉树的基本类型与存储结构详解
本文介绍了树和二叉树的基本概念及性质。树是由节点组成的层次结构,其中节点的度为其分支数量,树的度为树中最大节点度数。二叉树是一种特殊的树,其节点最多有两个子节点,具有多种性质,如叶子节点数与度为2的节点数之间的关系。此外,还介绍了二叉树的不同形态,包括满二叉树、完全二叉树、二叉排序树和平衡二叉树,并探讨了二叉树的顺序存储和链式存储结构。