热度 20
2013-12-10 15:25
1606 次阅读|
0 个评论
C51内存结构深度剖析 在编写应用程序时,定义一个变量,一个数组,或是说一个固定表格,到底存储在什么地方;当定义变量大小超过MCU的内存范围时怎么办;如何控制变量定义不超过存储范围;以及如何定义变量才能使得变量访问速度最快,写出的程序运行效率最高。以下将一一解答。 1 六类关键字(六类存储类型) data idata xdata pdata code bdata code: code memory (程序存储器也即只读存储器)用来保存常量或是程序。code memory 采用16位地址线编码,可以是在片内,或是片外,大小被限制在64KB 作用:定义常量,如八段数码表或是编程使用的常,在定义时加上code 或明确指明定义的常量保存到code memory(只读) 使用方法: char code table ; XBYTE =20; #define CWORD ((unsigned int volatile code *) 0) #define DWORD ((unsigned int volatile data *) 0) #define PWORD ((unsigned int volatile pdata *) 0) #define XWORD ((unsigned int volatile xdata *) 0) 功能:与前面的一个宏相似,只是它们指定的数据类型为unsigned int .。 通过灵活运用不同的数据类型,所有的8051地址空间都是可以进行访问。 如 DWORD =0x12F8; 即内部数据存储器中(0x08)=0x12; (0x09)=0xF8 注:用以上八个函数,可以完成对单片机内部任意ROM和RAM进行访问,非常方便。还有一种方法,那就是用指钟,后面会对C51的指针有详细的介绍。 4寄存器变量(register) 为了提高程序的执行效率,C语言允许将一些频率最高的那些变量,定义为能够直接使用硬件寄存器的所谓的寄存器变量。定义一个变量时,在变量类型名前冠以“register” 即将该变量定义成为了寄存器变量。寄存器变量可以认为是一自动变量的一种。有效作用范围也自动变量相同。由于计算机寄存器中寄存器是有限的。不能将所有变量都定义成为寄存器变量,通常在程序中定义寄存器变量时,只是给编译器一个建议,该变量是否真正成为寄存器变量,要由编译器根据实际情况来确定。另一方面,C51编译器能够识别程序中使用频率最高的变量,在可能的情况下,即使程序中并未将该变量定义为寄存器变量,编译器也会自动将其作为寄存器变量处理。被定义的变量是否真正能成为寄存器变量,最终是由编译器决定的。 5内存访问杂谈 1指钟 指钟本身是一个变量,其中存放的内容是变量的地址,也即特定的数据。8051的地址是16位的,所以指针变量本身占用两个存储单元。指针的说明与变量的说明类似,仅在指针名前加上“*”即可。 如 int *int_point; 声明一个整型指针 char *char_point; 声明一个字符型指针 利用指针可以间接存取变量。实现这一点要用到两个特殊运算符 取变量地址 * 取指针指向单元的数据 示例一: int a,b; int *int_point; //定义一个指向整型变量的指针 a=15; int_point=a; //int_point指向 a *int_point=5; //给int_point指向的变量a 赋值5 等同于a=5; 示例二: char i,table ,*char_point; char_point=table; for(i=0;i6;i++) { char_point=i; char_point++; } 注: 指针可以进行运算,它可以与整数进行加减运算(移动指针)。但要注意,移动指针后,其地址的增减量是随指针类型而异的,如,浮点指针进行自增后,其内部将在原有的基础上加4,而字符指针当进生自增的时候,其内容将加1。原因是浮点数,占4个内存单元,而字符占一个字节。 宏晶科技最新一代STC12C5A360S2系列,每一个单片机出厂时都有全球唯一身份证号码(ID号),用户可以在单片机上电后读取内部RAM单元F1H~F7H的数值,来获取此单片机的唯一身份证号码。使用MOV @Ri 指令来读取。下面介绍C51 获取方法: char id ={0}; char i; char idata *point; for(i=0;i7;i++) { id =*point; point++; } (此处只是对指针做一个小的介绍,达到访问内部任何空间的方式,后述有对指针使用的详细介绍) 2对SFR,RAM ,ROM的直接存取 C51提供了一组可以直接对其操作的扩展函数 若源程序中,用#include包含头文件,io51.h 后,就可以在扩展函数中使用特殊功能寄存器的地址名,以增强程序的可读性: 注 此方法对SFR,RAM,ROM的直接存取不建议使用.因为,淡io51.h这个头文件在KEIL中无法打开,可用指针,或是采用absacc.h头文件,