51单片机在Keil环境下,用C语言编程,关于片外存储区xdata中存放结构体类型的数据的问题,替朋友问的。

这个问题是替朋友问的,当然,我也不会,顺便请教,如果有回答的好的,我朋友可以充十块话费,先谢谢各位大神。

是这样的,本人以前一直做硬件设计,最近一年才接触单片机的硬件和编程设计,昨天在程序设计中,发现一个怪现象,就是,我程序里定义了一个结构体数据类型,如下定义:
typedef struct Calender
{
unsigned char Minute;
unsigned char Hour;
unsigned char Date;
unsigned char Month;
unsigned short Year;
}CALENDER;

CALENDER Calndr1;
CALENDER Calndr_Temp;

并且声明了两个个变量,Calndr1 和 Calndr_Temp,后来,因为程序不够,我把内存模式修改成Large模式,结果,程序就完全出错了,再后来,我找个高手问了一下,他说,51单片机的结构体数据类型所定义的变量和数组变量,是不可以放在外部RAM里的,至于详细的原因,他说他也不清楚,是经验所得的。

他后来只把变量的定义修改如下:
data CALENDER Calndr1;
data CALENDER Calndr_Temp;
程序在Large模式下就可以运行了,我想问问其他前辈,为什么自定义的结构体类型的数据不可以存放在外部存储器

XRAM里呢?
另外补充的说一下,我用的是STC90C516AD,有4K的外部RAM,是可以用的。
百度没分了,能给出详细且正确的解释的,我愿意充十块话费,谢谢!

Keil本身对STC单片机缺乏支持,对外部xram没有数据库描述。在器件库中选个带xram的单片机就可以了,比如sst89x516rd.追问

那为什么对于普通数据类型的变量没有问题,而自定义结构体类型的变量就不行呢?

追答

这个只能说是Keil对STC的支持问题,同样式51单片机,用SST的和C805F等带XRAM的就能正常编译通过,结构体是可以放在XRAM中的,不
存在你说的上述问题。还有声明结构体方法有问题。
typedef struct Calender
{
........

}CALENDER;

后面的这个CALENDER是一个变量,Calender才是变量类型。只有变量类型才能声明其他变量。这两个名称最好有所区别避免混淆。

追问

你没看明白,我是typedef struct xxx{}XXX.这种声明结构体的方法是没有问题的。

另外,我这个不是说把结构体类型放到外部RAM会编译报错,编译是不报错的,能够编译通过,只是运行出错。

追答

这个代码我验证过了,没有问题。而且我有很多项目上都在用外部RAM放结构体,不存在你说的问题。


你看那,我的结构体包括结构体的数组都定义到XRAM里了,

追问

非常感谢您能为这个问题亲自做实验!
如果 struct xxx{}XXX;这样的话,那么,XXX是一个声明的变量
typedef struct xxx{}XXX.如果是这样的话,其结构与 typedef unsigned short uint;是一样的,
那个uint是类型的新别名,而不是unsigned short类型的变量。

追答

嘿嘿,这个我弄错了,以我截图为准。你试着找找其他原因。

温馨提示:内容为网友见解,仅供参考
第1个回答  2013-07-01
单片机内部扩展RAM存储数据声明使用xdata。
修改内存模式,只是能使用的程序存储区的大小有变化,51的内存空间是不变的。至于报错我觉得是随着你的程序量增加所需要使用的内存也在增加。超过了256个字节。
你可以把报错信息贴出来,可以分析一下具体的原因。
当你使用关键字data声明后,结构体强制性的存放到内部内存,其它的有些内存变量可能被keil优化或者移到扩展内存了。
第2个回答  2013-07-01
CALENDER xdata Calndr1;
CALENDER xdata Calndr_Temp;
这样定义的出错了?
虽然没用过这个型号 但是51内核的 这样使用过 没出现过什么问题啊追问

是的,只要放到xdata里,程序就不对,数据就乱,但是放到data里就没有问题

追答

数据乱了是通过程序运行看出来的 还是仿真查看该地址时 数据是乱的
前者的话就好好检查下程序 看看是否是堆栈溢出了 后者的话有可能就是楼上所说keil的不支持引起的

追问

数据乱了是程序运行出来的,我用8个LED分别表示状态几种状态,只要把那个结构体类型定义在外部XRAM,状态跑的就不对,定义在内部就没有问题,您说是堆栈溢出,可是,我放到外部RAM的堆栈,减小了内部RAM的使用量,应该是增大了堆栈的空间才对呀?请前辈指教

追答

那你仿真看看 断点设在变量定义赋值之后 看变量是不是正确存放了

第3个回答  2024-04-09
我也是相同问题,定义了一个结构体,定义了一个该结构体类型的数组,含81个元素,在输入前52个数据赋值前52元素内时都正常,但在输入后面的数据时,不敢赋值什么数,元素都被赋值5。
请问你的问题和我一样吗?

在KEIL2中,定义idata,code,xdata分别是指定义的数据放在哪个存储区?
code区:单片机的内部程序存储区,也就是单片机内置的FALSH xdata区:单片机外部寻址区,一般指片外的存储器,0000H-FFFFH

51单片机访问片外数据存储器的用c怎么写
把变量声明成xdata 型的就可以了。如 unsigned char xdata ab[100];这些数据就存放在外部数据存储器了,但要求必须要真正地扩展了外部存储器,否则,读写数据就是错误的。不能自己骗自己吧。

在keil C51中使用结构体的问题
你的51单片机有512byte 那么肯定是 内部 直接 间接各128 外加外部256字节 你把那些大一点的数据全部改成 xdata 声明就可以了.当然如果你会控制ram大小的话..用idata 声明效率更好一点 例如 unsigned char yy;写个成 unsigned char xdata yy;(你看你自己的编译结果显示 data=137, xdata=0, code=...

在C语言中xdata是什么意思?
在C语言编程中,xdata是一个特殊的内存标识符,用于定义那些存储在外部扩展内存中的数据。在KEIL集成开发环境中,它主要用于指示变量的存储位置,即这些数据被放置在系统扩展内存区域。对于可变的数据,当你需要访问这些数据时,应使用MOVX指令,而不是内部寄存器常用的MOV指令,这样做可以避免内部寄存器空间的...

(单片机实际制作时)内外RAM的问题 (Keil软件 build窗口program size中...
1,DATA,51的内部RAM,只有128B(字节)大小,不管是最新的什么增强型单片机;2,XDATA,外部RAM,只能使用MOVX寻址 3,CODE,代码区,即是你的代码的大小,AT89C51为4K,C52为8K等,增强型的有更多的选择。然后说明一下,几种RAM的区别:1,DATA,也是上面1提到的DATA RAM,占51的128B;2,IDATA...

...C语言代码,编译过后会出现形如:Program Size: data=13.0 xdata...
data表示你使用的内部RAM,也就是地址在0~255之间的,用mov命令访问的RAM;xdata表示你使用的外部RAM,也就是需要用汇编movx才能访问的RAM,注意,很多扩展了RAM的51芯片,例如STC,华邦出品的51,虽然从使用者角度觉得是芯片自带的RAM,但实际上访问这些扩展RAM时是作为外部RAM处理的,你必须定义成xdata...

关于keil中的data和xdata 问题
“我用的单片机有512字节的空间”即使有额外的SRAM,一般也需要设置寄存器打开的。而且只扩256字节的型号一般映射到页内空间,需通过MOVX与@Ri访问。所以你可以试试PDATA方式。“我的程序中的变量超过114字节就编译不通过了”应当将部分变量分配到内部间接寻址区,如下:unsigned char idata ucMyVariable;...

MCS-51系列单片机,变量定义为外部数据(XDATA),但没有扩展外部数据存储器...
你用C编辑器(KEIL)编辑的时候是编辑的过去的,但你下载到单片机开始执行程序后,你所有写到外部地址的数据就丢失了,等在用到这个变量,在读就不对了~

在51单片机c语言中在不同存储器中的设定变量关键字有哪些?
允许位与字节混合访问(0X20-0X2F,16字节)idata (indirect)间接寻址片内数据存储区,访问片内全部RAM空间(8052,256字节)pdata (page)分页寻址外部数据存储区(256字节)由MOVX @R0访问xdata (extend)片外数据存储区(64KB),由MOVX @ DPTR访问。Code 代码存储区(64KB),由MOVC @DPTR访问 ...

用C语言给51单片机编程时,怎样用P0口输出地址和数据?
只要C语句能保证编译出MOVX指令即可。你可以自行学习以下关键字的用法:pdata,xdata PBYTE,XBYTE 点到为止。剩下的自己去琢磨,Keil里面都能搜索到的。

相似回答