《第15章C51的存储结构.ppt》由会员分享,可在线阅读,更多相关《第15章C51的存储结构.ppt(28页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、第15章 C51的存储结构C51是面向51系列单片机的硬件控制系统开发语言,其和单片机的硬件资源有着密切的联系。C51的程序经过编译后,是要在单片机上运行的。因此,程序代码以及数据都是需要按照一定的存储类型保存在8051单片机的特定存储区中的。存储结构的组织形式是单片机C51语言很重要的组成部分。本章将介绍C51的存储结构、存储类型和动态内存分配函数等相关内容。15.1 存储器结构存储器结构是存储器的组织形式。51系列单片机采用哈佛结构,将程序代码存储器(ROM)和数据存储器(RAM)分开,各自遵循各自的寻址机构和寻址方式。这里概括一下51系列单片机存储器的硬件构成。15.1.1 51系列单片
2、机的存储区域51系列及其兼容单片机在物理上划分为4个存储区:片内数据存储区片外数据存储区片内程序存储区片外程序存储区早期的单片机片内存储器比较小,最近新推出的51内核单片机在存储器方面有了很大的扩展。每个存储区的大小和用法,可以参阅不同型号单片机的说明。15.1.2 片内数据存储器(RAM)的结构C51程序中的变量一般保存在片内数据存储器,这样取址速度快。当然变量也可以保存在片外数据存储区,这将在后面进行介绍。51系列单片机内部数据存储器(RAM)可划分为2大区域。00H7FH:片内低128字节RAM区80H0FFH:特殊功能寄存器区(SFR)对于地址为00H07FH的低128字节片内RAM区
3、,又可划分为3个区域:1通用寄存器区2可位寻址区3用户RAM区15.2 存储类型存储类型是指程序中变量和常量等在8051硬件系统中的存放方式。Keil Vision3编译器完全支持8051系列单片机的硬件结构,可完全访问8051单片机硬件系统的所有部分,并将数据定位在不同的硬件存储区中。单片机C51语言中支持的存储类型有data、bdata、idata、pdata、xdata、code几种。在8051系列单片机的硬件系统中,存储类型与存储区关系,如表所示。15.2.1 data存储类型将变量设置为data存储类型的一般形式如下:标识符 data 变量名其中,data为关键字,标识符为变量的类型
4、。在51单片机系统中,对data区寻址是最快的。所以一般来说,应将频繁使用的变量设置为data型。例如:int data ch5;char data string6;float data flo;MyType data newtype;/自定义的数据类型15.2.2 bdata存储类型将变量设置为bdata存储类型的一般形式如下:标识符 bdata 变量名其中,bdata为关键字,标识符为变量的类型。bdata区是可位寻址数据存储器,可以将要求可位寻址的数据定义为bdata。例如:unsigned charbdata ie;/在位寻址区定义字符变量ieint bdata mn10;/在位寻址区
5、定义整型数组mn10sbit ie5=ie5;/用关键字sbit定义位变量来可寻址对象其中一位sbit mn8=mn18;15.2.3 idata存储类型将变量设置为idata存储类型的一般形式如下:标识符 idata 变量名其中,idata为关键字,标识符为变量的类型。idata类型为间接寻址片内数据存储区,可访问片内全部的256字节RAM地址空间。例如:extern floatidata tt;/在位寻址区定义浮点型变量tt注意:idata区可以定义浮点型变量。15.2.4 pdata存储类型将变量设置为pdata存储类型的一般形式如下:标识符 pdata 变量名其中,pdata为关键字,
6、标识符为变量的类型。pdata类型存储在分页寻址外部数据存储区,例如:unsigned charpdata pun;/在位寻址区定义字符变量pun15.2.5 xdata存储类型将变量设置为xdata存储类型的一般形式如下:标识符 xdata 变量名其中,xdata为关键字,标识符为变量的类型。对xdata区寻址,须装入16位地址,因此尽量将外部数据存放在xdata区。例如:#include/头文件#include/头文件unsigned char pdata RX1;/声明xdata变量unsigned char pdata RX2;/声明xdata变量void main()/主函数whil
7、e(1)RX1=P1;/赋值RX2=P3;/赋值 15.2.6 code存储类型将变量设置为code存储类型的一般形式如下:标识符 code 变量名其中,code为关键字,标识符为变量的类型。例如:char code text=”Hello everyone!”;/在code区定义字符串数组使用code存储类型定义数据时,C51编译器会将其定义在程序代码储存器(ROM或者EPPROM)。在使用上面几种存储类型时,因为访问内部数据存储器比访问外部数据存储器快,所以应将频繁使用的变量放在内部RAM中,将很少使用的变量放在外部RAM中。15.3 扩展数据类型扩展数据类型是8051硬件和C51编译器所
8、特有的,不属于ANSIC标准。这些类型的数据可以操作8051的特殊功能寄存器,而不能用指针对其进行存取。扩展数据类型可由以下几种关键字说明。sfr:用于字节寻址,定义8位特殊功能寄存器。例如:sfr P0=0 x80;/为P0口地址为80H后的一个字节;sfr P1=0 x90;/为P1口地址为90H后的一个字节。sfr16:用于字寻址,定义16位特殊功能寄存器,且该16位必须低位在低字节,高位在紧跟德高字节才行。例如:sfr16 T2=0 xCC;15.3.1 sfr和sfr16sfr和sfr16可以用于定义8051的特殊功能寄存器,其一般形式如下:sfr 特殊功能寄存器名=特殊功能寄存器地
9、址常数;sfr16 特殊功能寄存器名=特殊功能寄存器地址常数;其中,sfr和sfr16为关键字。特殊功能寄存器的定义示例如下:sfr P2=0 xA0;/定义P2的I/O端口,其地址为A0Hsfr16 T2=0 xCC;/定义定时器2,其地址T2L=CCH,T2H=CDH15.3.2 sbitsbit用于定义可位寻址对象,例如特殊功能寄存器某位。在C51语言中,有如下几种定义方法:sbit 位变量名=位地址。该语句用于将位地址赋值给位变量名,例如:sbit P1_1=0 x91;/将位的绝对地址赋给位变量这里需要注意的是,sbit的位地址必须位于80HFFH之内。sbit 位变量名=特殊功能寄
10、存器名位位置。该语句使用符号“”来获得位数据,并赋值给位变量。例如:sfr P1=0 x90;/定义一个特殊功能寄存器名sbit P1_1=P11;/指定位变量名所在的位置sbit 位变量名=字节地址位位置。该语句和第二种方法是一样的,只是将特殊功能寄存器名用位地址常数直接表示。例如:sbit P1_1=0 x901;15.3.3 bit型变量bit型变量可用于变量类型、函数声明、函数返回值等场合,其定义的一般形式为:bit 变量名采用bit定义的位变量存放于内部RAM(20H2FH)。位变量在C语言里是外部变量,但编译系统不对其初始化,必须在程序中初始化位变量。例如:extern bit b
11、ch;15.4 存储模式存储模式是编译环境中指定的变量的存储区形式。一般来说,如果在定义变量时默认存储类型,编译系统将按照存储模式所规定的默认存储区来指定变量、函数参数等的存储区域。Keil Vision编译系统支持的8051系列单片机存储模式共三种:15.4.1 Small模式Small模式用于将所有未指明存储区的变量均装保存在内部RAM,即采用data存储类型方式。采用Small模式的优点是访问速度快,缺点是空间有限,需要节约使用存储空间,只适用于规模较小的程序。15.4.2 Compact模式Compact模式用于将所有未指明存储区的变量均装保存在外部RAM区的一页(256Bytes)内
12、,即采用pdata存储类型方式。采用Compact模式的优点是存储空间较Small模式宽裕,缺点是访问速度要慢些,但较下面介绍的Large模式要快,是一种中间状态。Compact模式适用于变量不超过256字节,可以通过P2口指定地址的高字节。15.4.3 Large模式Large模式用于将所有未指明存储区的变量放在多达64KB的外部RAM区中,即采用xdata存储类型方式。采用Large模式的优点是空间大,可存变量多,缺点是速度较慢。Large模式使用数据指针DPTR来对变量进行寻址。15.4.4 存储模式的选择存储模式一般是在C51编译器选项中进行选择,也可以在程序中指定。在程序中指定存储模
13、式的形式如下:void fun1(void)small 该语句声明函数fun1,用small说明函数内部变量全部保存在内部RAM。对于一些经常使用的和特别耗时的地方可以这样声明,有利于提高运行速度。15.5 C51的存储器指针在C51语言中支持一般指针和存储器指针。对变量进行声明时可以指定变量的存储类型。同样,在对于指针变量声明的时候,也可以指定存储类型。下面分别进行介绍。15.5.1 一般指针一般指针的声明在前面已经介绍过,不过同时还可以说明指针的存储类型。例如:long*state;/state为指向long型整数的指针,则依存储模式存放char*xdata ptr;/ptr为一个指向ch
14、ar数据的指针,放于外部RAM区一般指针可存放于任何存储器中,其用3个字节存放,分别为存储器类型、高位偏移、低位偏移量。使用一般指针时,可以访问数据而不用考虑其在存储器的位置,因此十分方便。15.5.2 存储器指针存储器指针在声明时指定了存储类型,其总是指向特定的存储区。例如:char data*str;/str指向data区中char型数据int xdata*pow;/pow指向外部RAM的int型整数由于存储器的类型已经指定了,因此这种指针存放时,只需存放偏移量即可。对于idata、data、bdata和pdata存储类型只需一个字节,对于code和xdata存储类型需要2个字节就够了。1
15、5.5.3 指针存储类型与指针所指向的数据的存储类型的关系指针存储类型与指针所指向的数据的存储类型是不同的概念,在使用时一定要注意。例如:uchar xdata tmp10;/在外RAM区占10个字节的内存空间(0 x00000 x0009)uchar data*data pstr;pstr=tmp;其中tmp保存在外部RAM,访问外RAM需要2字节来寻址64k空间,而pstr使用data关键字,所以编译器将其编译成指向内部RAM的指针变量了。最后的赋值语句便是错误的。上面的语句可以改为:uchar xdata tmp10;uchar xdata*data pstr;pstr=tmp;15.6
16、 动态内存分配动态内存分配用于对一些动态结构进行存储空间的分配。其中这些动态结构可以是树和链表等。对于大多数情况,应尽可能在编译的时候确定所需要的内存空间,并进行分配,例如数组的大小需要明确指定。而对于一些程序,采用动态内存分配可以实现数据的灵活处理。15.6.1 C51的动态分配函数在C51语言中提供了多个动态内存分配函数。这些函数要求用户声明一个字节数组作为堆,根据所需要的动态内存大小来决定数组的长度,被声明的数组存放在xdata区中,库函数可以使用特定指针来进行寻址。C51提供的动态分配函数示例如下所述。init_mem():此函数的功能是初始化动态内存区的程序源代码。可以指定动态内存的
17、位置及大小,只有使用了init_mem()才可以调回其他函数,如malloc、calloc、realloc等。calloc():此函数是给数组分配内存,可以指定单位数据类型及该单元数目。malloc():此函数的功能是分配一段固定大小的内存。realloc():此函数的功能是调整当前分配动态内存的大小。free():此函数的功能是重新分配空间。15.6.2 malloc()和calloc()函数malloc()和calloc()函数都是用来动态分配内存空间的。但两者在使用时稍有区别,主要体现在函数形式以及内存空间的分配上。malloc()函数和calloc()函数具有不同的使用形式,下面分别进行讲解:malloc()函数的形式示例如下:void*malloc(size_t size);其中包含一个参数unsigned int,即要分配的内存空间的大小,该函数返回一个指针。calloc()函数的形式示例如下:void*calloc(size_t numElements,size_t sizeOfElement);15.7 小结本章详细讲述了C51语言的存储器结构、存储类型、存储模式以及存储器指针等,后面还介绍了动态内存分配。数据的存储模式是单片机系统特有的概念,这里的内容涉及单片机的硬件资源比较多,用户应该对照着单片机的介绍来进行学习,这样可以加深理解。
限制150内