第3章 存 储 结 构 微课视频 本章以AT89C51为模型机,介绍MCS51系列单片机存储结构。 3.1基本特性 采用哈佛型存储结构,程序存储器和数据存储器在物理上是分开的,具有独立的寻址机构和寻址指令。程序存储器采用EPROM、EEPROM或Flash存储器,数据存储器采用静态存储器(SRAM)或动态存储器(DRAM)。 内部集成4KB程序存储器(ROM)、256B数据存储器(RAM),可外部扩展64KB(最大)程序存储器(ROM)和64KB(最大)数据存储器(RAM)。 在物理结构上,存储系统可以分为4个存储空间,即片内RAM、片内ROM和片外RAM、片外ROM,如图31所示。 图31存储系统地址分布 3.2程序存储器 程序存储器用来存放程序和数据表格,采用16位程序计数器(PC)和16位地址总线,最大寻址空间为64KB。 程序存储器物理上可分为片内和片外两部分,共享64KB程序存储地址空间。 用引脚EA确定CPU对内部程序存储器和外部程序存储器的使用选择。 当EA=0时,CPU 从外部ROM的0000H单元开始执行程序。当EA=1时,从内部ROM的0000H单元开始执行,当地址超过4KB时自动转向外部ROM的1000H单元。 片内程序存储区0000H~002AH作为系统保留使用。 0000H~0002H单元: 主程序入口地址。复位时程序计数器PC=0000H,指向该单元。该单元存放一条绝对跳转指令(SJMP),跳转到主程序首地址。 0003H~000AH单元: 外部中断INT0中断服务程序入口地址。该单元存放一条绝对跳转指令(SJMP),跳转到INT0中断处理程序首地址。 000BH~0012H单元: 定时/计数器T/C0溢出中断处理程序入口地址。该单元存放一条绝对跳转指令(SJMP),跳转到T/C0溢出中断处理程序首地址。 0013H~001AH单元: 外部中断INT1中断服务程序入口地址。该单元存放一条绝对跳转指令(SJMP),跳转到INT1中断处理程序首地址。 001BH~0022H单元: 定时/计数器T/C1中断服务程序入口地址。该单元存放一条绝对跳转指令(SJMP),跳转到T/C1溢出中断处理程序首地址。 0023H~002AH单元: 串行口通信中断服务程序入口地址。该单元存放一条绝对跳转指令(SJMP),跳转到串行通信中断处理程序首地址。 3.3数据存储器 系统中RAM分为内部RAM和外部RAM两部分,用 MOV 指令访问内部数据存储单元,用 MOVX 指令访问外部数据存储单元。 3.3.1数据存储器地址分布 片内和片外数据存储器地址分布如图32所示。 图32片内和片外数据存储器地址分布 图33片内RAM地址分布 3.3.2片内RAM 片内RAM按功能划分为工作寄存器区、位寻址区、数据缓冲区(RAM)和特殊功能寄存器(SFR)区四个区域,地址空间分配见图33。 1. 工作寄存器区 地址范围为00H~1FH,32字节,分为4组,每组8个寄存器,标识为R0~R7。任何时刻只有一组作为当前工作寄存器组使用,由程序状态字PSW中的RS1和RS0选择,见表31。 表31当前寄存器组选择 RS1 RS0 工作组寄存器(地址) 0 0 0组(00H~07H) 0 1 1组(08H~0FH) 1 0 2组(10H~17H) 1 1 3组(18H~1FH) 通过软件设置RS1、RS0以设置当前寄存器组。单片机复位后,默认0组为当前工作寄存器组。 2. 位寻址区 地址范围为20H~2FH,16字节,共计16×8=128位。每个单元有一个字节地址,字节地址范围为20H~2FH。每位有一个位地址,位地址范围为00H~7FH。位寻址区每一位都可作为一个软件触发器使用,通常把各种状态、位控制变量保存在位寻址区。 3. 数据缓冲区 地址范围为30H~7FH,用户数据区,共80字节单元,用作用户的数据存储区。堆栈也可设置在该区域。 4. 特殊功能寄存器区 地址范围为80H~FFH,特殊功能寄存器(SFR)区。系统把片内寄存器和I/O端口映射在该区域存储单元,对I/O端口的操作实际上就是对相应存储单元的操作。 SFR字节地址见表32。 表32SFR字节地址 标识符 名称 地址 标识符 名称 地址 ACC累加器E0H BB寄存器F0H PSW程序状态字D0H SP堆栈指针81H DPTR数据指针83H/82H P0端口080H P1端口190H P2端口2A0H 续表 标识符 名称 地址 标识符 名称 地址 P3端口3B0H IP中断优先级B8H IE中断允许A8H TMOD定时/计数方式89H TCON定时/计数控制88H TH0定时/计数0初值8CH TL0定时/计数0初值8AH TH1定时/计数1初值8DH TL1定时/计数1初值8BH SCON串口控制寄存器98H SBUF串口数据寄存器99H PCON电源控制寄存器97H 3.3.3特殊功能寄存器 系统特殊功能寄存器映射为内部数据存储器的存储单元,每个特殊功能寄存器都有相应单元地址。 1. 程序计数器(PC) 16位地址寄存器,存放将要执行的指令地址,寻址范围为0000H~FFFFH(64KB)。 复位时PC=0000H,即系统复位后,CPU从程序存储器ROM的0000H单元开始执行程序。 2. 数据指针(DPTR) 由2个8位寄存器构成,高8位寄存器DPH和低8位寄存器DPL构成16位的寄存器DPTR,用来存放外部RAM的地址,作为CPU访问外部RAM的数据指针。 CPU的查表指令使用DPTR提供ROM中表格的首地址。CPU访问外部RAM中的数据或ROM中的表格、常数,必须借助DPTR作指针来实现数据的读取访问。 3. 程序状态字(PSW) 8位寄存器,表征程序执行的状态信息,各位定义如图34所示。 D7 D6 D5 D4 D3 D2 D1 D0 CY AC F0 RS1 RS0 OV — P 图348位寄存器定义 CY(PSW.7): 进位标志。在加减法运算中,累加器A的最高位D7有进位或借位,则CY=1,否则CY=0。 AC(PSW.6): 辅助进位位。在加减法运算中,累加器A的低4位向高位4位有进位或借位,则CY=1,否则CY=0。 F0(PSW.5): 用户标志位。由用户来定义和使用。 RS1,RS0: 当前工作寄存器组选择位。选定当前工作寄存器组。 OV(PSW.2): 溢出标志位。当运算结果溢出时,OV置1。 P(PSW.0): 奇偶标志位。累加器A中1的个数为奇数个时为1,A中1的个数为偶数时为0。 图35堆栈结构 4. 堆栈指针(SP) 8位寄存器,指示堆栈栈顶地址。 堆栈是在内存单元专门用来按照先进后出方式存取的区域。在使用堆栈之前,先给SP赋值,以规定堆栈的起始位置,称为栈底。在数据压入堆栈后,SP内容自动加1,随着数据不断进栈,SP向上增长,如图35所示。 系统复位后,SP总是初始化到内部RAM地址07H。堆栈有专门访问指令PUSH和POP。 3.4最小系统 由AT89C51构成的最小系统见图36,包括时钟电路、上电复位电路和按键复位电路。系统运行点亮一个LED,R1为LED限流电阻。 图36最小系统 注: 本书电路图由Proteus 7.0绘制,器件符号遵循国际规范。 【应用举例】 #include <reg51.h> //C51包含文件 sbit LED=P2^0; //定义LED控制位 void main() { LED=1; //点亮发光二极管 while(1); } 习题 1. 片内程序存储器00H~2AH系统保留单元的作用是什么? 2. 简述哈佛存储结构的特点和意义。 3. 简述工作寄存器组的结构及设置工作寄存器组的意义。 4. 什么是堆栈?其作用是什么? 5. 简述程序计数器(PC)的工作过程。 第二部分单片机C语言程序设计 用C语言进行嵌入式系统开发已成为业界主流,也是单片机教学的首选。C语言程序设计是“单片机原理与技术”课程的先修课程,用于MCS51系列单片机开发的C语言称为C51,在数据类型、程序结构、基本语句上,与C语言有非常大的相似度。本部分在先修课程C语言程序设计基础上,介绍C51的数据类型、程序结构和函数设计,突出C51特有的数据类型、存储类型及其对特殊功能寄存器、位寻址的定义和应用。 本部分包括: 第4章数据类型与基本运算 本章介绍C51的程序结构与数据类型,介绍变量和常量的存储器类型定义及其在单片机程序设计中的作用,讲述C51的基本运算和复合运算。 第5章程序控制语句 本章介绍条件语句if、开关语句switch的基本语法,以实现程序的有条件跳转与分支。讲述while、do while 和for 语句设计方法和语法要求,实现循环体结构的程序设计。 第6章函数 函数是模块化程序设计的核心,也是提高程序设计水平的关键技能。本章介绍C51函数的定义、说明、调用及参数传递。 第4章 数据类型与基本运算 微课视频 4.1C51程序结构 用于MCS51系列单片机开发的C语言称为C51,在数据类型、程序结构、基本语句、平台使用等方面,C51与C语言有非常大的相似度。 1. C51 由于具有良好的结构性和模块化,用C语言书写的程序容易阅读和维护,具有良好的可移植性,功能化的代码能够很方便地从一个工程移植到另一个工程。 相对于汇编语言,用 C语言编写程序更符合人类的思考习惯,开发者可以更专心考虑算法,而不必十分熟悉处理器的工作过程。 C51支持所有51系列单片机开发,Keil μVision提供了良好的C51开发和调试环境。 2. 程序结构 下面为一个简单而完整的C51程序,实现最小系统点亮一个LED的功能,接口电路见图41。 图41最小系统接口 #include <reg51.h> //C51包含文件 sbit LED=P2^0; void main() //主程序 { LED=1; //点亮发光二极管 while(1); } 该程序在KEIL平台上编辑、编译、连接、运行后,可驱动连接在P2.0引脚上的LED发光。 C51程序数据类型、语法、语句、函数定义等类似于一般C语言程序。 C51应用程序有且只有一个主函数main(),作为程序运行的入口。 {}中间的内容为程序的主体,称为程序体。 C51用//和/*...*/对程序中的任何部分作注释。