51单片机ram区域划分
51单片机的RAM分为片内和片外,标准的51内核是0x00~0x7F一共128B,而现在的大多数半导体厂商开发的51系列单片机都带了扩展片内RAM,即片内RAM区域一般是从0x00到0xFF一共256B。随着功能需求越来越多,程序量越来越大,那片内这256B也不够用了,因此又扩展了片外RAM,片外RAM的预留比较大,最大可以从0x0000到0xFFFF一共64KB,当然了,每个具体型号有多大不一定,具体看通过芯片的手册来了解。
而现在的51单片机的片外RAM, “片外”只是一个名词而已,实际上很多也是直接做到了单片机内部,但是访问地址,还是以外部的起始地址的方式。就是说,片内RAM的地址从0x00到0xFF,而片外是从0x0000到0xFFFF;其中最开始的256B是重复的地址,这部分通常情况下只要RAM够用就可以不理会,软件编译器会自动给我们处理好。当选默认small模式,优先使用内部的前128B,而选Large模式,优先使用的是片外的64K。因此上面那个同学的问题就在这里了,因为他用的是AT89S51单片机,而这个单片机是没有片外RAM的,如果选择了Large模式,那优先使用的是片外,因此编译完成,下载到单片机里,程序运行时用了这个单片机所没有的区域,那肯定就不行了。
通常KEIL C51语言中的以下几个关键字,代表了RAM不同区域的划分:
data:片内RAM从0x00~0x7F
idata:片内RAM从0x00~0xFF
pdata:片外RAM从0x00~0xFF
xdata:片外RAM从0x0000~0xFFFF
其中,data是idata的一部分,pdata是xdata的一部分。这个问题我们可以不关心,只和汇编编程有关。
那如果选择了small模式,我们定义一个变量a:unsigned char a = 0;他是默认保存在data区域,这个时候data是可以省略,但是我们想定义到xdata区域,就必须前边加xdata关键字:unsigned char xdata a = 0;
如果选择large模式,unsigned char a = 0;是定义在片外xdata区域,如果要定义在片内就必须加data关键字。
但是在RAM够用的情况下,我们优先使用data的,其次使用idata关键字,再次使用pdata关键字,最后使用xdata。这个和底层访问指令有关系,用前边的读写速度要快一些,比如pdata访问是单字节地址,而xdata是双字节地址,访问速度就慢了。