最近写单片机总会遇到一些关于数据存储类型和指针的相关问题,所以特整理此篇方便以后查看。
一、C51变量的数据类型
C51的数据类型
| 数据类型 | 长度 | 值域 |
位型 | bit | 1bit | 0或1 |
字符型 | signed char | 1Byte | -128~127 |
unsigned char | 1Byte | 0~255 | |
整型 | signed int | 2Byte | -32768~+32768 |
unsigned int | 2Byte | 0~65535 | |
signed long | 4Byte | -2147483648~+2147483647 | |
unsigned long | 4Byte | 0~4294967295 | |
实型 | float | 4Byte | 1.176E-38~3.40E+38 |
指针型 | data/idata/pdata | 1Byte | 1字节地址 |
code/xdata | 2Byte | 2字节地址 | |
通用指针 | 3Byte | 其中1字节为存储类型编码,2、3字节为地址偏移量 | |
访问SFR 的数据类型 | sbit | 1bit | 0或1 |
sfr | 1Byte | 0~255 | |
sfr16 | 2Byte | 0~65535 |
说明:对于字符型、整型和长整型均有有符号和无符号型两种,如果不是必需,尽可能选择unsigned型,
这将会使编译器省却符号位的检测,使生成的程序代码比signed类型短得多。
二、数据的存储类型和存储模式
存储类型 描述
data 直接寻址片内数据存储器的低128字节,访问速度最快
bdata 可位寻址内部数据存储区,允许位与字节混合访问(16B)
idata 间接寻址内部数据存储区,可访问安全部内部地址空间(256B)
pdata 分页(256B)外部数据存储区,由操作码MOV@Ri访问
pdata 分页(256B)外部数据存储区,由操作码MOV@Ri访问
xdata 外部数据存储区(64KB),由操作码MOVX@Ri访问
code 代码存储区(64KB),由操作码MOVC@A+DPTR访问
访问内部数据存储器(idata)比访问外部数据存储器(xdata)相对要快一些,因此,通常将经常使用的变量置于内部数据存储器中,而将较大及很少使用放入数据变量置于外部数据存储器中。
例如:
data char x;/*字符变量x定位在片内数据存储区。等同于char data x;*/
如果用户没有对变量的存储类型定义,则编译器承认默认存储类类型,默认存储类型由编译控制命令的存储模式部分决定。
在Keil里面通过 Option for target/Target/Memory Model 设置存储模式。
三、存储器模式
存储器模式决定了变量的默认存储器类型,参数传递区和无明确存储区类型的说明。C51的存储器模式有SMALL、LARGE和COMPACT。C51也支持混合模式。例如在LARGE模式下生成的程序可将一些函数分页放在SMALL模式中,从而加快执行速度。
存储器模式 描述
SMALL 参数及局部变量放入可直接寻址的内部存储器(最大为128B,默认存储器类型为data)
COMPACT 参数及局部变量放入分页外部存储区(最大为256B,默认存储器类型为pdata)
LARGE 参数及局部变量直接放入外部数据存储器(最大为64KB),默认存储器类型为xdata
四、指针变量说明举例
指针本身是一个变量,包括存放的存储区和数据长度。因此在指针类型的定义中要说明:被指的变量的数据类型和存储类型;指针变量本身的数据类型(占几个字节)和存储类型(即指针本身存在哪个存储区)。
例如:
long xdata *px; <span style="font-family: Arial, Helvetica, sans-serif;">/*指针px指向long型xdata区(每个数据占4个单元,指针 自身在默认存储器)指针长度为两个字节*/</span>
char xdata * data pd; /*指针pd指向字符型xdata区,自身在data区,长度为两个 字节*/
/*定义一个人类型为int型的通用型指针,指针自身在data区,长度为3个字节*/
data int * pn;//等效于int * data pn 及int * pn