Ⅰ 关于单片机存储器的问题,idata,data,badata,xdata,pdata,code,片内存储区,片外存储区都是些什么关系啊
关于51单片机内存问题,一直是个疑惑大家的问题,因为51单片机是个很另类的单片机。
下面我给楼主讲解一下:
51单片机之所以另类,是因为,他寻址内存的空间,不是靠总线,是用指令的方式。
51单片机有以下几个内存模块组成:
1】ROM或者Flash,叫程序存储区,你写的程序是存在这里面的,上电后从这里面执行。
程序存储区也分为片内和片外,一般来说,现在的51很多已经做到了64K,所以很少有外扩
片外Flash或者片外的Rom了,Flash或者Rom不管是片内还是片外的,只能用来定义常量,是用code来修饰,也就是说,用code来修饰的东西,在程序运行过程中,不能修改;
2】RAM有------内部RAM的低128位(00-7F),对应C语言就是data,比如我定义一个变量,
data unsigned char Var = 0;
那么,这个 Var变量就是放在内部的低128位Ram中
-------内部RAM的高128位(80-FF),对应C语言就是idata,比如我定义一个变量,
idata unsigned char Var = 0;
那么,这个 Var变量就是放在内部的高128位Ram中
-------特殊功能寄存器(SFR)(80-FF),对应C语言就是Sfr比如我定义一个变量,
Sfr unsigned char Var = 0x90;
那么,这个 Var变量就是放在内部的特殊功能寄存器中,这是你对Var操作,相当于操作一个特殊的寄存器,但是小心,不能随便定义Sfr变量,很危险
------外部RAM 64K(0000-FFFF)
外部的RAM可以扩展到65536个,但是前256个算是一页,这一页比较特殊,是用
pdata来修饰的,当然,也可以用xdata来修饰。
除了第一页的256个以外的其他65280个空间,只能用xdata来修饰;
回过头来讨论pdata和xdata,这两个都能修饰外部Ram的第一页,但是,Pdata只能修饰第一页,即最前面的256个外部Ram,那么,这最前面的256个到底用Pdata还是Xdata好的呢?
答案是Pdata,因为Xdata修饰的变量,用的是DPTR寻址,Pdata用的是R0和R1.DPTR因为是16位的,所以可以覆盖整个的64K外部Ram,R0和R1是8位,所以只能寻址最前面的256个,也就是外部Ram的第一页,但是,用R0寻址,比DPTR快一倍,代码也小的很多
楼主又疑惑了,好多地址是重复的,比如,我向80H地址写一个数值,单片机怎么知道读的是内部的高128位RAM?还是SFR?还是外部64K的RAM呢?
答案是用指令,如果是直接寻址,那么访问的就是SFR,如果是R0或者R1间接寻址,就是内部高128位RAM,如果是DPTR或者是R0,R1间接寻址,且配合的是MovX指令,那么就是访问外部64KRAM中的第80H个地址。
概括一下来说,51的内存由以下组成:
1----程序存储器(包括片内Flash或Rom,也包括片外Flash或Rom,C语言用Code定义)
2----内部低128位Ram,C语言用data定义
3---内部高128位Ram,C语言用idata定义
4---内部SFR,C语言用Sfr定义
5---外部65536个Ram(通常,很多单片机厂家不会给你扩展那么多的,一般来说扩展256个字节或者1024个字节就差不多了,最近宏晶的出了个扩展4096字节的。这65536字节的Ram,前256个可以用Pdata修饰,也可以用Xdata修饰,超过256个之后的,只能用Xdata修饰)
以上所说的只是针对51内核的单片机,其他内核的,像ARM之类的,不是这种结构的。
最后,回答楼主的问题:
片外存储区是什么?
这个问题太模糊,答案可以是外扩的Flash,也可以说是外扩的RAM,
如果问题是这么问的:
程序或者常量存储在片外存储区,这个片外存储区指的是什么?
答案是外扩Flash;
如果问题是---变量存储在片外存储区,这个片外存储区指的是什么?
答案是外扩RAM;
一般来说,如果不指明的话,外内存储区,行业内人士指的是外部的Ram。
片内存储器是什么?是不是就是内部的E2PROM?
片内存储区一般来说,指的是内部的Ram,包括高128位(idata)和低128位(data)
片内存储器,这个说法我没听说过,可能是EEPROM吧。
Ⅱ Keil中data和idata,pdata,xdata以及code的区别
使用软件之前,要养成阅读软件帮助的良好习惯,而不是到处东问西问!
Cx51的存储类型:Cx51通过以下的关键字定义了不同的存储类型,从而确保能够访问到51架构的全部存储空间。
code:访问程序存储器(默认仅限于标准51能够寻址的64kB空间内),生成的代码主要通过 MOVC @A+DPTR实现。
data:访问可直接寻址的片内存储器(标准51的低128字节),从而实现对变量最高速的访问。
idata:访问间接寻址的片内存储器(标准51的256字节)。
bdata:访问位寻址的片内存储器(标准51中从20H开始的16字节),支持位+字节的混合访问模式。
xdata:访问外部数据存储器(默认仅限于标准51能够寻址的64kB空间内),生成的代码主要通过MOVX @A+DPTR实现。
far:扩展的RAM及ROM访问方式,最大支持16MB寻址空间,至于生成的代码方式则取决于用户自定义的访问程序或特定的芯片类型(例如恩智浦的80C51MX、Dallas390等)。
pdata:访问当前页面内的外部数据存储器(256字节),生成的代码主要通过MOVX @Ri实现。
Ⅲ STC89C52,51增强型单片机内部资源问题
关于STC89C52:
1、STC89C52只有512字节的的RAM,包括2部份,一是256字节的内部RAM,二是256字节的外部RAM;STC89C54以上的芯片才有1K的RAM(内256+外1024)。
2、1K的EEPROM(应为2K)出厂时内置有支持串行下载功能的代码,配合官方下载软件完成代码的串口下载。这个区域在实际应用当中也可用于可保存断电后不能丢失的数据,但实际操作上不能像RAM那样直接读写,需要通过专门的寄存器操作来完成读写。
3、EEPROM不是ROM,也不是RAM,EEPROM也没有用作RAM--你先这样记,这个问题说起来内容比较多,后面细谈。
4、Flash程序存储器8K就是当ROM用(这句话严格的讲应该说成“Flash程序存储器8K就是当程序存储器用”):基本上是这样。关于ROM、FALSH后面细说。
是否需要1K的RAM:可在编译完成后观察编译结果,如果能编译成功,应该有类似下面的信息:“program size:data=9.0,xdata=1,code =2345”,其中data的整数部份就是你实际需要的内部RAM字节数,xdata是你实际需要的外部RAM字节数,code是代码长度。你可以根据这个信息选择最合适的STC单片机型号。具体到STC89C52:data<256,xdata<256,code<8192就行
对上述的一些概念补充说明(包括_at_)
1、51单片机的C语言中有个需要关注的概念就是变量或数据的存储模式(PC机是否有类似的情况我不了解)。在C51中的存储模式是data、bdata、idata、pdata、xdata、code共6种:
data、bdata、idata:就是说变量或数据位于单片机的内部RAM中(ST89C52有256字节),访问速度最快。
pdata、xdata:就是说变量或数据位于扩展的外部RAM中(ST89C52内集成了256字节),相对内部RAM访问速度要慢。
code:就是程序代码,位于单片机的程序存储其中(ST89C52内含8192字节)
KEIL C编译时在有个选项叫数据存储模式(Memory Model),如果选择小模式,则程序中的变量一般会放在内部RAM(data)中,选择其它模式则会放在外部RAM(xdata或pdata,采用这两种存储模式的变量在物理上都放在外部RAM中,只是寻址方式有所不同,整体上pdata更快些);当然,如果在定义变量时就声明了存储模式,编译时会根据声明决定该变量在哪个区。比如:char data flag就是指定将flag放在内部RAM中;char xdata flag _at_0x0000则指定放在外部RAM中,而且地址是0x0000。
"_at_" 用于指定变量在内存中的地址。指定地址的方法优点在于调试方便,比如仿真单步运行时可以直接到该地址去更直观的观察变量的实际变化情况,若不指定则编译器会自己决定放在什么地方,只能通过.M51文件去获取该变量的地址了。其缺点则是容易出错,由于人为的因素,可能会成各变量的地址重叠。所以实际应用中一般都不指定地址,编译器会自动安排的,除非是特殊要求。
这里针对内部RAM和外部RAM再说几句:早先的单片机(8031、8032)外部RAM和程序存储器都需要通过P0口P2口来扩展的,51单片机本身没有哪怕是1个字节的外部RAM,扩展起来很麻烦。后来随着发展才演变到现在几乎所有的单片机都或多或少的集成了RAM和程序存储器,这样大多数应用只需要设计功能电路就可以了,不需要再去扩展,这就降低了不少成本。
2、关于FLASH、ROM、PROM、EPROM、EEPROM、RAM
我们现在一般都会把单片机的程序存储器叫ROM,早先的硬件程序代码确实是放在ROM型的器件中(包括电脑的BIOS),所以ROM就是程序、程序就是ROM,大家都理解,就成习惯了。其实这是不对的,真正的ROM现在很少用了。下面就这几个名词解释一下:
RAM:一般都叫内存,特点是读写速度快,但断电后数据丢失(后5种断电后数据不丢失)
ROM:只读存储器。特点是只能读,其内容在芯片出厂时就已经固化,如果有错只能扔掉
PROM:可编程只读存储器。特点是实际应用中只能读,但应用产品生产环节可由用户来完成对芯片的编程,只能写1次,有错的话下场同ROM。
EPROM:可重复擦写的只读存储器。特点是实际应用中只能读,但可以通过紫外线擦除(也有电擦除的),从而实现再编程,只是编程时一般需要将芯片取下来在专用设备上擦除、编程(电擦除的虽然可以在用户系统上实现擦除及编程,但必须设计专门的擦除编程电路)。上世纪90年代基本上都采用的是这种模式,如果你看到某个芯片上有个小玻璃窗,一般就是这种工艺的芯片。紫外线擦除需要15分钟的时间,也很麻烦,而且映像中编程次数只有1000次。
EEPROM:可重复擦写的非易失性存储器。特点是可读可写,且断电后数据不丢失。采取这种工艺的芯片大多数都是通过IIC总线模式来访问的。但其容量一般都不大,适合于数据不多的应用。
FLASH:可重复擦写的非易失性存储器。特点是可读可写,且断电后数据不丢失。与EEPROM的主要区别在于口线更多、存储容量更大、速度更快,还有就是擦写方式不同:EEPROM可按字节擦写,而FLASH是块擦写模式,所以速度上FALSH的读写更快。
STC单片机为什么要采取EEPROM的模式而不采用FLASH我不知道,可能是因为EEPROM相对成本较低,而且可以直接用作非易失性存储,不需要用户外扩EEPROM了。
Ⅳ 一个关于Keil C关键字xdata和data的问题
1.xdata表示这是一个外部RAM地址内的数据,数据最终将被保存至外部RAM的某个地址单元中;
但是,外部RAM只能通过寄存器间接寻址来访问,也就是说,其地址需要保存在内部RAM中(其实或许是SFR中,8位地址一般是R0、R1,16位地址一般通过DPTR间址)
这里,DPTR里保存的内容就相当于指向外部RAM单元的指针了…… 所以,用了内部数据类型(data)的指针,和外部数据类型(xdata)
2. 这里变量pAddress应该是指针型变量,所以给pAddress赋值应是外部地址, *pAddress才是在外部RAM地址的内容,因此它的数据类型是xdata(换句话说,pAddress是指针,*pAddress是指针指向的数据)
Ⅳ KEIL 编程 如何使用XDATA
如果是汇编,XDATA的很好访问,直接用MOVX指令,访问的就是XDATA,比如:
MOVDPTR,#1000H
MOVXA,@DPTR
如果是C语言,那么声明变量时加上xdata就可以了。比如
#include<reg51.h>
unsignedintxdataa;
main()
{
a=0x5a;
printf("%d",a);
while(1);
}
也可以采取另一种方式来访问XDATA,比如:
#include<reg51.h>
#include<absacc.h>
#defineucharunsignedchar
#defineuintunsignedint
//PA、PB、PC端口及命令端口地址定义
#definePAXBYTE[0x0000]
#definePBXBYTE[0x0001]
#definePCXBYTE[0x0002]
#defineCOMXBYTE[0x0003]
//待显示字符编码队列
ucharcodeDSY_CODE_Queue[]={
0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xa4,0xc0,0xc0,0x80,0xc0,0x80,0xf9,
0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff
};
//数码管选通
ucharcodeDSY_Index[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//延时
voidDelayMS(uintms)
{
uchari;
while(ms--)for(i=0;i<120;i++);
}
//主程序
voidmain()
{
uinti,j,k;
COM=0x80;//8255工作方式选择:PA、PB均输出,工作方式0
while(1)
{
for(j=0;j<40;j++)//刷新显示一段时间
{
for(k=0;k<8;k++)//在8个数码管上显示字符
{
PB=DSY_Index[k];//位码
PA=DSY_CODE_Queue[k+1];//段码
DelayMS(1);
}
}
i=(i+1)%15;//刷新显示一段时间后递增i,形成滚动效果,最大索引为14
}
}
Ⅵ 51单片机定义一个大数组存在idata与xdata中有什么区别
51单片机定义一个大数组存在idata与xdata区别为:空间不同、访问不同、获取不同。
一、空间不同
1、idata:idata占用51单片机内部RAM的固定0x00-0xff空间。
2、xdata:xdata占用51单片机外部RAM扩展的0x0000-0xffff空间。
二、访问不同
1、idata:idata用类似C中的指针方式进行访问。
2、xdata:xdata用DPTR进行访问。
三、获取不同
1、idata:51单片机编译成功后,在idata区中,可以直接获取到定义的数组。
2、xdata:51单片机编译成功后,在xdata区中,不可以直接获取到定义的数组。
Ⅶ 关于单片机内存问题,DATA和XDATA具体是怎么样的
选择small 模式你定义的变量默认为data模式,即变量存放与单片机的内部ram,而large模式下,定义的变量存放于外部ram。前者运算速度快于后者。
Ⅷ 单片机 keil编程中我把data数据改成xdata类型,编译无误,但程序运行不了!为什么急!
编译肯定不会报错,你改xdata只不过C编译器编译成MOVX @DPTR这样的指令,如果没有外扩存储器,可定跑不起来。而且我有一点疑问的是你把data用了接近128 Bytes,你主函数定义的变量很多还是用了iteration?
我怀疑你是不是data空间里面你是不是很多的constant,constant建议放在内部FLASH中,使用movc @dptr查表。
可以用pdata申明变量,用mov @Ri间接寻址方式访问内部全部的256bytes空间!
Ⅸ 关于keil中的data和xdata 问题
“我用的单片机有512字节的空间”
即使有额外的SRAM,一般也需要设置寄存器打开的。而且只扩256字节的型号一般映射到页内空间,需通过MOVX与@Ri访问。所以你可以试试PDATA方式。
“我的程序中的变量超过114字节就编译不通过了”
应当将部分变量分配到内部间接寻址区,如下:
unsigned char idata ucMyVariable;