在C51中对变量进行定义的格式如下:
【存储种类】数据类型 【存储器类型】 变量名列表;
其中存储种类和存储器类型是可选项,当变量名列表中的变量不止一个时,用逗号隔开。
存储种类:4种
自动(auto),外部(extern),静态(static)和寄存器(register)
存储器类型:6种
DATA区、BDATA区、IDATA区、PDATA区、XDATA区、CODE区 指明该变量所处的内存空间
存储模式: 3种
SMALL、COMPACT和LARGE 指明了变量在没有指明存储器类型时默认的存储区域
1、存储种类自动(auto)变量
当变量的生命周期结束时,它所占的内存单元也就被释放。定义变量时省略存储种类,则该变量默认为自动变量。
外部(extern)变量
假设一个变量在函数体外或别的程序中已被定义过,并且在本函数体内要使用该变量,则该变量要在本函数体内用extern 说明。用extern定义的变量称为外部变量。外部变量被定义后,在程序的执行过程中都是有效的。
静态(static)变量
用static定义的变量称为静态变量。静态变量在程序调用结束后其占用的内存单元并不被释放(其值保持不变)。
寄存器(register)变量
用register声明的变量称为寄存器变量。该类变量速度最快,应该存放使用频率最高的变量。通常C51编译器会自动识别程序中使用频率最高的变量,并自动将其作为寄存器变量,程序员无需专门声明。
变量的存储种类和存储器类型是不一样的。存储器类型指明该变量所处的内存空间。单片机内部有程序存储器和数据存储器。数据存储器又分为片内存储器和片外存储器。而片内存储器又分为低128字节和SFR特殊功能寄存器。
C51存储类型使用不同的存储器类型,程序会有不同的执行效率,在编写C51程序时,推荐指定变量的存储器类型,这样有利于提高程序的执行效率。
若省略存储器类型,编译器将根据使用的存储器模式(SMALL,COMPACT,LARGE)来规定默认的存储器类型。
2、六种存储器类型片内RAM:DATA区、 BDATA区、 IDATA区
(1) DATA区
该区速度最快,所以应该存放使用频率最高的变量。但是该区资源有限,除了存放变量外,还包含堆栈和寄存器组。一旦该区资源不够,会使程序发生莫名其妙的错误。
固定指前面0x00-0x7f的128个字节RAM,可以用acc直接读写的,速度最快,生成的代码也最小。
变量定义举例: char data i[10];
(2) BDATA区
在该区定义的变量,可以进行位寻址,并且可以声明位变量。它可以单独使用变量的某一位,而不一定要用位变量名引用位变量。
注意该区不允许定义float类型的变量。
(3) IDATA区
该区使用寄存器间接寻址,可以存放使用比较频繁的变量。变量定义举例: float idata var;
固定指前面0x00-0xff的256个字节RAM,其中前128和data的128完全相同。
片外RAM:PDATA区、 XDATA区
(4) PDATA区
该区只有一页即256字节,具体哪一页由P2口指定。使用MOVX指令进行数据传送。
片外xdata的0X00–0XFF那一段,使用R0,R1间接寻址。
变量定义举例: long PDATA var
(5) XDATA区
该区和PDATA区类似,只是空间增大了——64KB。对XDATA的寻址比对PDATA的寻址要慢(前者需要装入16位地址,而后者只需要装载8位地址)。进行数据传送时同样需要使用MOVX指令。
变量定义举例:unsigned char XDATA i;
(6) CODE区
该区为程序存储器,代码区中的数据一旦写入不可擦除不可重写。在该区中一般存放数据表,跳转向量和状态表等。变量定义举例:
变量定义举例:unsigned char CODE da[3]={0x04,0x58,0x56};
对于片外扩展I/O口,则要根据其硬件译码地址,将其视为片外数据存储器的一个单元,在程序的开始位置使用#define 定义:
一旦在头文件或程序中对这些片内外I/O口进行定义以后,在程序中就可以自由使用这些I/O口了。
3、存储模式存储模式指明了变量在没有指明存储器类型时默认的存储区域,共有:SMALL、COMPACT和LARGE三种。
(1)SMALL模式
所有的缺省变量,参数都存储在内部RAM中,优点:存储速度快,执行效率高。缺点:内部RAM有限,只适合小程序。
(2)COMPACT模式
所有缺省变量都存储在外部RAM的一页(256字节)中。具体哪一页可由P2口指定,该模式空间较SMALL模式充裕,速度较SMALL模式慢,较LARGE模式快,是一种中间模式。
(3)LARGE模式
所有参数变量都放在片外数据存储器中,容量大,但速度慢。
通过#pragma定义,例如#pragma small。
4、C51的指针指针类型和存储区的关系:
对变量进行声明时可以指定变量的存储类型如:
uchar data x和data uchar x相等价都是在内ram区分配一个字节的变量。
1、普通指针:未指定指针指向
char * ptr; //指针占3字节,第一字节是标识存储类型,第二字节是指针高位字节,第三字节是指针低位字节
char * xdate ptr; //指针存储在片外char * idate ptr; //指针存储在片内指针指向的数据可以是片内也可以是片外,由于片外数据地址在0x0000-0xffff之间,片内数据地址在0x00-0xff之间,在未指定数据存储在片内还是片外的情况下,指针长度按固定3个字节:一字节标识存储类型+ 一字节高位地址+ 一字节低位地址。
存储类型部分代表了该指针所指向的变量的存储器类型,存储类型的代码如下:
2、内存特殊指针:指定指针指向:
char xdate * ptr;//在指定指针指向之后,指针就只需要表明地址即可,指针为1个字节或2个字节( one byte (idata, data, bdata, and pdata pointers) or two bytes (code and xdata pointers)),xdate是修饰 *的,也就是数据存储在片外,此时ptr占两个字节 char idate * ptr;//数据是片内,指针ptr只有一个字节char xdate * date ptr; //指针存放在片内,数据在片外,指针为2个字节总结:内存特殊指针比一般指针运行快,因为数据存储位置知道,编译时可以优化 指针类型可以转换,但容易出错。所以编程时最好对数据和对指针的修饰都要。
内存特殊指针和普通指针实例对比3、指针的绝对地址赋值
char xdata * XROM;
XROM=(char xdata *)0xB012;//指针XROM的值就是0xB012,(char xdata *)表示强制类型转换
XROM=‘r’;//给0xB012的地址内容赋值r
a=((char xdata *)0xB012);//等同于a=*XROM,此时a=‘r’
|