《例说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地址位置开始执行,如没有遇到跳转指令,则按程序存储器地址顺序执行。当然,程序存储器前面几个位置还有一些玄机,留待中断的单元再详细说明。

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

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

(2)每组寄存器组都包含R0~R7共8个寄存器,而任一时刻只能使用其中一组寄存 器组。
(3)寄存器组的切换可以用程序状态字寄存器(Program Status Word,PSW)中的RS1与RS0来决定,如表1-4所示。

(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《例说51单片机(C语言版)(第3版)》——1-3 认识MCS-51的存储器结构的更多相关文章
- 51单片机C语言学习笔记6:51单片机C语言头文件及其使用
很多初学单片机者往往对C51的头文件感到很神秘,而为什么要那样写,甚至有的初学者喜欢问,P1口的P为什么要大写,不大写行不行呢?其实这个是在头文件中用sfr定义的,现在定义好了的是这样的 sfr P1 ...
- [新概念51单片机C语言教程·郭天祥] 1、 基础知识必备
目录: 单片机的大致介绍 1-1.通俗定义 1-2.51系列产品 1-3.标号意思 1-4.引脚介绍 1-5.用C语言开 ...
- 51单片机C语言学习笔记3: 存储器结构
MCS-51单片机在物理结构上有四个存储空间: 1.片内程序存储器2.片外程序存储器3.片内数据存储器4.片外数据存储器 但在逻辑上,即从用户的角度上,8051单片机有三个存储空间: 1.片内外统一编 ...
- 51单片机学习笔记(清翔版)(13)——LED点阵、74HC595
如图3,点阵屏分单色和彩色,点阵屏是由许多点组成的,在一个点上,只有一颗一种颜色的灯珠,这就是单色点阵屏,彩色的在一个点上有三颗灯珠,分别是RGB三原色. 图4你可能没看出来,那么大块黄色的就是点阵屏 ...
- 51单片机C语言学习笔记8:单片机C51编程规范
1.单片机C51编程规范- 前言 为了提高源程序的质量和可维护性,从而最终提高软件产品生产力,特编写此规范. 2.单片机C51编程规范-范围 本标准规定了程序设计人员进行程序设计时必须遵循的规范.本 ...
- 51单片机C语言学习笔记4:keil C51绝对地址访问
在利用keil进行8051单片机编程的时,常常需要进行绝对地址进行访问.特别是对硬件操作,如DA AD 采样 ,LCD 液晶操作,打印操作.等等.C51提供了三种访问绝对地址的方法: 1. 绝对宏: ...
- 51单片机C语言学习笔记5:include的区别
#include <iostream.h>#include "myfile_h" #include 是预处理器标识符.<>表示是标准的工程.标准的头文件.查 ...
- 51单片机C语言学习笔记7:关于.c文件和.h文件
1)h文件作用 1 方便开发:包含一些文件需要的共同的常量,结构,类型定义,函数,变量申明: 2 提供接口:对一个软件包来说可以提供一个给外界的接口(例如: stdio.h). 2)h文件里应该有什么 ...
- 51单片机学习笔记(清翔版)(21)——ADDA数模转换
A:anolog模拟的 D:digital数字的 AD模拟转数字,DA数字转模拟 生活中的基本都是模拟量,如温度,可以是10℃,10.1℃等 手机的背光亮度自动调节,拿到太阳光下,亮度 ...
- 外置式与增量式PID模板程序(51单片机c语言)
外置式PID模板 #define MuBiaoCS 0 //目标常数 #define CHang_aCS 0 //比例常数 #define CHang_bCS 0 //积分常数 #define CHa ...
随机推荐
- SpringCloud(三)之我学 Hystrix
1.断路器 在消费服务的启动类,添加注解:@EnableCircuitBreaker,在消费服务的调用类上,添加注解:@HystrixCommand(fallbackMethod = "&q ...
- linux 配置 python3 CGI
文章更新于:2020-03-04 注1:安装 python 参见: python 的安装使用和基本语法 注2:配置 web 环境参见: Windows&linux使用集成环境搭建 web 服务 ...
- css进阶选择器
后代选择器 用空格隔开 选择div标签下的p标签下的a标签 div p a 选择class为parent标签下的p标签下的a标签 .parent p a 后代选择器可以是标签.类.id的混合体 后代选 ...
- wireshark抓包实战(四),数据包的操作
1.标记数据包 当我们找到一个数据包感觉它很重要时,想要让它更明显怎么办呢?让它高亮即可! 具体操作: 选中某个条目,右键mark即可 2.为数据包添加注释 选中包以后,右键"分组注释&qu ...
- "多行文本"组件:<multi> —— 快应用组件库H-UI
 <import name="multi" src="../Common/ui/h-ui/text/c_text_multi"></impo ...
- not found 什么时候触发
eq: BEGIN DECLARE EXIT HANDLER FOR NOT FOUND SET o_state = 999; select count(1) into ...
- 使用malloc和free函数进行内存动态分配
一.在学习c语言里面,内存分配这个话题非常有意思,因为我们平时在开发的时候,如果一不小心没注意内存释放的话,写的的程序很容易出错,所以今天就来回顾一下c语言里面的内存动态分配,下面我们先来看一个实例来 ...
- @ModelAttribute 的使用
@ModelAttribute注解可被应用在 方法 或 方法参数 上. 对方法使用 @ModelAttribute 注解: 注解在方法上的@ModelAttribute说明了方法的作用是用于添加一个或 ...
- Sprint 5 summary: UI 界面更新,Azure端部署和用户反馈分析 12/28/2015
本次sprint主要完成的任务有对手机APP的UI界面的更新,同时对Azure客户端的部署进行了相应的学习和有关的程序设计.同时对于ALPHA release的用户反馈做出相应的分析以确定接下来工作的 ...
- Android | 教你如何在安卓上实现通用卡证识别,一键各种卡绑定
目录 前言 通用卡证识别的应用场景 如何使用通用卡证识别服务 集成通用卡证识别服务的关键流程 开发实战 1 开发准备 1.1 在项目级gradle里添加华为maven仓 1.2 在应用级的build. ...