目录
一.C51的数据类型和存储类型
1.数据类型:
2.C51的扩展数据类型:
3.数据存储类型
4.数据存储模式
二.特殊功能寄存器及其位变量定义
1.特殊功能寄存器的C51定义
2.位变量的C51定义
三.C51语言的绝对地址访问
1.绝对宏
2._at_关键字
一.C51的数据类型和存储类型
1.数据类型:
针对8051的硬件特点,C51在标准C基础上,扩展了4种数据类型
注意,扩展的4种数据类型,不能使用指针来对它们存取
2.C51的扩展数据类型:
(1) 位变量bit的值可以是1 (true),也可是0 (false)
(2) 特殊功能寄存器sfr。8051单片机的特殊功能寄存器分布在片内数据存储区的地址单元80H~FFH之间,“sfr”数据类型占用一个内存单元利用它可访问8051单片机内部的所有特殊功能寄存器。
例如:sfr P1=0x90这一语句定义了P1端口在片内的寄存器,在程序后续的语句中可以用“p1=0xff”,使P1的所有引脚输出为高电平的语句来操作特殊功能寄存器。
SFR特殊功能寄存器的名称及分布如下:
注:当位地址的尾数是0或8时,是可以进行位寻址的
(3) 特殊功能寄存器sfr16
“sfr16”数据类型占用两个内存单元,用于操作占两个字节的特殊功能寄存器。例如:“sfr16 DPTR=0x82”语句定义了片内16位数据指针寄存器DPTR,其低8位字节地址为82H,高8位字节地址为83H。在程序的后续语句中就可对DPTR进行操作。
(4) 特殊功能位sbit
sbit是指AT89S51片内特殊功能寄存器的可寻址位。
符号”^“前是特殊功能寄存器名字,““^”后的数字定义特殊功能寄存器可寻址位在寄存器中的位置,取值必须是0~7。
注意,不要把bit与sbit相混。bit定义普通的位变量,只能是0或1。sbit是定义特殊功能寄存器的可寻址位,值是可以进行位寻址的特殊功能寄存器的某位的绝对地址,例如,PSW寄存器OV位的绝对地址0xd2。
3.数据存储类型
在讨论C51数据类型时,须同时提及它的存储类型,以及它与8051单片机存储器结构的关系,因为C51定义的任何数据类型必须以一定的方式,定位在8051单片机的某一存储区中,否则没有任何实际意义
8051有片内、片外数据存储区,还有程序存储区
片内的数据存储区是可读写的,8051的衍生系列最多可有256字节的内部数据存储区(例如AT89S52单片机),其中低128字节可直接寻址,高128字节(80H~FFH)只能间接寻址,从地址20H开始的16字节可位寻址。
内部数据存储区可分为3个不同的数据存储类型: data、idata和bdata。
访问片外数据存储区比访问片内数据存储区慢,因为访问片外数据存储区要通过对数据指针加载地址来间接寻址访问
C51提供两种不同的数据存储类型xdata和pdata来访问片外数据存储区
程序存储区只能读不能写,可能在8051单片机内部或者外部,或外部和内部都有,由8051单片机硬件连线决定,C51提供了code存储类型来访问程序存储区。
C51语言存储类型与8051存储空间的对应关系:
C51存储类型及其大小和值域
(1) DATA区。寻址最快,应把常使用的变量放在该区,但该区存储空间有限,DATA区除了包含程序变量外,还包含了堆栈和寄存器组。DATA区声明中的存储类型标识符为data,i通常指片内RAM128字节的内部数据存储的变量,可直接寻址。
标准变量和用户自声明变量都可存储在DATA区中,只要不超过DATA区的范围即可,由于C51用默认的寄存器组来传递参数,这样DATA区至少失去8字节空间。
另外,当内部堆栈溢出的时候,程序会莫名其妙地复位。这是因为8051没有报错机制,堆栈溢出只能以这种方式表示,因此要留有较大的堆栈空间来防止堆栈溢出。
(2) BDATA区。DATA中的位寻址区,在该区中声明变量就可进行位寻址。BDATA区声明中的存储类型标识符为bdata,指的是片内RAM可位寻址的16字节存储区(字节地址为20H~2FH)中的128个位。
(3)IDATA区。该区使用寄存器作为指针来对片内RAM进行间接寻址常用来存放使用比较频繁的变量。与外部存储器寻址相比,它的指令执行周期和代码长度相对较短。
IDATA区声明中的存储类型标识符为idata,指的是片内RAM的256字节的存储区,只能间接寻址,速度比直接寻址慢。
(4)PDATA区和XDATA区 位于片外存储区,PDATA区和XDATA区声明中的存储类型标识符分别为pdata和xdata。
PDATA区只有256字节,仅指定256字节的外部数据存储区。
但XDATA区最多可达64KB,对应的xdata存储类型标识符可指定外部数据区64KB内的任何地址。
对PDATA区的寻址要比对XDATA区寻址快,因为对PDATA区寻址,只需装入8位地址,而对XDATA区寻址要装入16位地址,所以尽量把外部数据存储在PDATA区中。
由于外部数据存储器与外部1/0口是统一编址的,外部数据存储器地址段中除了包含数据存储器地址外,还包含外部1/0口的地址。
(5)程序存储区CODE。程序存储区CODE声明的标识符为code,储存的数据不可改变。在C51编译器中可用存储区类型标识符code来访问程序存储区声明举例如下:
单片机访问片内RAM比访问片外RAM相对快一些,所以应尽量把频繁使用的变量置于片内RAM。即采用data、bdata或idata存储类型,而将容量较大或使用不太频繁的那些变量置于片外RAM,即采用pdata或xdata存储类型。常量只能采用code存储类型。
应用举例:
4.数据存储模式
如果在变量定义时略去存储类型标识符,编译器会自动默认存储类型
进一步由SMALL、COMPACT和LARGE存储模式指令限制。例如,若声明char var1,则在使用SMALL存储模式下,var1被定位在data存储区,在使用COMPACT模式下,var1被定位在idata存储区;在LARGE模式下,var1被定位在xdata存储区中。
下面对存储模式作进一步说明
(1)SMALL模式。该模式下,所有变量都默认位于8051单片机内部的数据存储器,与使用data指定存储器类型的方式一样。在此模式下,变量访问的效率高,但是所有数据对象和堆栈必须使用内部RAM。
(2) COMPACT模式
本模式下所有变量都默认在外部数据存储器的1页 256字节)内,这与使用pdata指定存储器类型是一样的。该类型适用于变量不超过256字节的情况,此限制是由寻址方式决定的,相当于使用数据指针@Ri寻址。与SMALL模式相比,该存储模式的效率比较低,对变量访问的速度也慢一些但比LARGE模式快。
(3) LARGE模式
本模式下所有变量都默认位于外部数据存储器,相当于用@DPTR寻址通过数据指针访问外部数据存储器的效率较低,特别是当变量为2字节或更多字节时,该模式要比SMALL和COMPACT产生更多的代码。
二.特殊功能寄存器及其位变量定义
1.特殊功能寄存器的C51定义
直接引用编译器提供的头文C51语言允许通过使用关键字sfr、sbit或来对特殊功能寄存器(SFR)进行访问特殊功能寄存器分布在片内RAM高128字节中,只能采用直接寻址方式。
(1)使用关键字定义sfr。为能直接访问特殊功能寄存器SFR,C51提供了种定义方法,即引入关键字sfr,语法如下:
在8051中,要访问16位SFR,要用关键字sfr16。16位SFR的低字节地址须作为“sfr16”的定义地址,例如:
(2) 通过头文件访问SFR。各种衍生型的8051单片机的特殊功能寄存器的数量与类型有时是不相同的,对其访问可通过头文件访问来进行
为用户处理方便,C51把8051(或8052单片机)常用的特殊功能寄存器和其中的可寻址位进行了定义,放在一个reg51.h (或reg52.h)的头文件中。
当用户要使用时,只需在使用之前用一条预处理命令include<reg51.h>把这个头文件包含到程序中,就可使用特殊功能寄存器名和其中的可寻址位名称了。用户可对头文件进行增减。
(3)特殊功能寄存器中的位定义。对SFR中的可寻址位的访问,要使用关键字来定义可寻址位,共3种方法:
2.位变量的C51定义
由于8051可位操作,C51扩展的“bit”数据类型用来定义位变量,这是与标准C的不同之处。
定义位变量时,允许定义存储类型,位变量都被放入一个位段,此段总是位于8051的片内RAM中,因此其存储类型限制为DATA或IDATA,如果将位变量定义成其他类型,将会导致编译时出错。
三.C51语言的绝对地址访问
如何对8051片内RAM、片外RAM及1/0空间进行访问,C51提供两种常用的访问绝对地址的方法
1.绝对宏
编译器提供了一组宏定义对code、data、pdata和xdata空间进行绝对寻址。
程序中用“#include<absacc.h>”来对absacc.h中声明的宏来访问绝对地址,包括CBYTE、CWORD、DBYTE、DWORD、XBYTE、XWORD、PBYTE、PWORD具体使用参见absacc.h头文件。其中:
2._at_关键字
其中,存储器类型为C51能识别的数据类型,数据类型为C51支持的数据类型;地址常数用于指定变量的绝对地址,必须位于有效的存储器空间之内;使用 _at _定义的变量必须为全局变量