51单片机的data,idata,xdata,pdata的详解

来源:互联网 发布:浙江黄金宝软件 编辑:程序博客网 时间:2024/04/30 02:43

1、80C51单片机存贮空间的分配

空间名称地址范围说明DATAD:00H~7FH片内RAM直接寻址区BDATAD:20H~2FH片内RAM位寻址区IDATAI:00H~FFH片内RAM间接寻址区XDATAX:0000H~FFFFH64KB常规片外RAM数据区HDATAX:0000H~FFFFFFH16MB扩展片外RAM数据区CODEC:0000H~FFFFH64K常规片内外ROM代码区HCONST(ECODE)C:0000H~FFFFFFH16MB扩展片外ROM常数区(Dallas390可用作代码区)

BANK0

     ~

BANK31

B0:0000H~FFFFH

        ~

B31:0000H~FFFFH

分组代码区,最大可扩展32X64KB ROM



(1)data: 固定指前面0x00-0x7f的128个RAM,可以用acc直接读写的,速度最快,生成的代码也最小。

(2)bit :是指0x20-0x2f的可位寻址区。

(3)idata:固定指前面0x00-0xff的256个RAM,其中前128和dATa的128完全相同,只是因为访问的方式不同。 
idata是用类似C中的指针方式访问的。 
汇编中的语句为:mox ACC,@Rx.(不重要的补充:c中idATa做指针式的访问效果 很好)  
(4)xdata: 外部扩展RAM,一般指外部0x0000-0xffff空间,用DPTR访问。

(5)pdata: 外部扩展RAM的一页,具体是哪一页,可由P2口定义,并在STARTUP.a51文件中说明。一般默认的是外部RAM低256个字节,地址出现在A0-A7的上时读写,用movx ACC,@Rx读写。这个比较特殊,而且C51好象有对此BUG,建议少用。但也有他的优点,具体用法属于中级问题,这里不提。 

(6)bdata如何使用它呢?

若程序需要8个或者更多的bit变量,如果你想一次性给8个变量赋值的话就不方便了,(举个例子说说它的方便之处,想更深入的了解请在应用中自己琢磨)又不可以定义bit数组,只有一个方法
char bdata MODE;
sbit MODE_7 = MODE^7;
sbit MODE_6 = MODE^6;
sbit MODE_5 = MODE^5;
sbit MODE_4 = MODE^4;
sbit MODE_3 = MODE^3;
sbit MODE_2 = MODE^2;
sbit MODE_1 = MODE^1;
sbit MODE_0 = MODE^0;
8个bit变量MODE_n 就定义好了。


2、指针类型和存储区的关系 
     对变量进行声明时可以指定变量的存储类型如:  
     uchar data x和data uchar x相等价都是在内ram区分配一个字节的变量。 
     同样对于指针变量的声明,因涉及到指针变量本身的存储位置和指针所指向的存储区位置不同而进行相应的存储区类型关键字的 
使用如: 
     uchar xdata * data pstr  
     是指在内ram区分配一个指针变量("*"号后的data关键字的作用),而且这个指针本身指向xdata区("*"前xdata关键字的作用), 
可能初学C51时有点不好懂也不好记。没关系,我们马上就可以看到对应“*”前后不同的关键字的使用在编译时出现什么情况。 
     ......  
     uchar xdata tmp[10];     //在外ram区开辟10个字节的内存空间,地址是外ram的0x0000-0x0009  
     ......  

     第1种情况:  
     uchar data * data pstr;  
     pstr="tmp";  
     首先要提醒大家这样的代码是有bug的, 他不能通过这种方式正确的访问到tmp空间。 为什么?我们把编译后看到下面的汇编 
代码: 
     MOV 0x08,#tmp(0x00)         ;0x08是指针pstr的存储地址 
     看到了吗!本来访问外ram需要2 byte来寻址64k空间,但因为使用data关键字(在"*"号前的那个),所以按KeilC编译环境来说 
就把他编译成指向内ram的指针变量了,这也是初学C51的朋友们不理解各个存储类型的关键字定义而造成的bug。特别是当工程中的 
默认的存储区类为large时,又把tmp[10] 声明为uchar tmp[10] 时,这样的bug是很隐秘的不容易被发现。 
     

    第2种情况:  
     uchar xdata * data pstr;  
     pstr = tmp;  
     这种情况是没问题的,这样的使用方法是指在内ram分配一个指针变量("*"号后的data关键字的作用),而且这个指针本身指向 
xdata区("*"前xdata关键字的作用)。编译后的汇编代码如下。 
     MOV 0x08,#tmp(0x00)         ;0x08和0x09是在内ram区分配的pstr指针变量地址空间 
     MOV 0x09,#tmp(0x00)  
     这种情况应该是在这里所有介绍各种情况中效率最高的访问外ram的方法了,请大家记住他。 
     

    第3种情况:  
     uchar xdata * xdata pstr;  
     pstr="tmp";  
     这中情况也是对的,但效率不如第2种情况。编译后的汇编代码如下。 
     MOV DPTR, #0x000A         ;0x000A,0x000B是在外ram区分配的pstr指针变量地址空间 
     MOV A, #tmp(0x00)  
     MOV @DPTR, A  
     INC DPTR  
     MOV A, #tmp(0x00)  
     MOVX @DPTR, A  
     这种方式一般用在内ram资源相对紧张而且对效率要求不高的项目中。 
     

    第4种情况:  
     uchar data * xdata pstr;  
     pstr="tmp";  
     如果详细看了第1种情况的读者发现这种写法和第1种很相似,是的,同第1 种情况一样这样也是有bug的,但是这次是把pstr分 
配到了外ram区了。编译后的汇编代码如下。 
     MOV DPTR, #0x000A         ;0x000A是在外ram区分配的pstr指针变量的地址空间 
     MOV A, #tmp(0x00)  
     MOVX @DPTR, A  
     

    第5种情况:  
     uchar * data pstr;  
     pstr="tmp";  
     大家注意到"*"前的关键字声明没有了,是的这样会发生什么事呢?下面这么写呢!对了用齐豫的一首老歌名来说就是 “请跟我 
来”,请跟我来看看编译后的汇编代码,有人问这不是在讲C51吗? 为什么还要给我们看汇编代码。C51要想用好就要尽可能提升C51  
编译后的效率,看看编译后的汇编会帮助大家尽快成为生产高效C51代码的高手的。还是看代码吧! 
     MOV 0x08, #0X01             ;0x08-0x0A是在内ram区分配的pstr指针变量的地址空间 
     MOV 0x09, #tmp(0x00)  
     MOV 0x0A, #tmp(0x00)  
     注意:这是新介绍给大家的,大家会疑问为什么在前面的几种情况的pstr指针变量都用2 byte空间而到这里就用3 byte空间了 
呢?这是KeilC的一个系统内部处理,在KeilC中一个指针变量最多占用 3 byte空间,对于没有声明指针指向存储空间类型的指针, 
系统编译代码时都强制加载一个字节的指针类型分辩值。具体的对应关系可以参考KeilC的help中C51 User’s Guide。 
     

    第6种情况:  
     uchar * pstr;  
     pstr="tmp";  
     这是最直接最简单的指针变量声明,但他的效率也最低。还是那句话,大家一起说好吗!编译后的汇编代码如下。 
     MOV DPTR, #0x000A         ;0x000A-0x000C是在外ram区分配的pstr指针变量地址空间 
     MOV A, #0x01  
     MOV @DPTR, A  
     INC DPTR  
     MOV DPTR, #0x000A  
     MOV A, #tmp(0x00)  
     MOV @DPTR, A  
     INC DPTR  
     MOV A, #tmp(0x00)  
     MOVX @DPTR, A  
     这种情况很类似第5种和第3种情况的组合,既把pstr分配在外ram空间了又增加了指针类型的分辨值。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 建行网银u盾丢了怎么办 深水区换气时喝了口水怎么办 撞到别人车了 我走了 怎么办 自己班同学被自己取好多外号怎么办 刚学会走路的宝宝脚外八字怎么办 宝宝两岁走路膝盖弯曲不直怎么办 一岁多的宝宝走路o型腿怎么办 21个月的宝宝走路o型腿怎么办 宝宝十一个月了0型腿怎么办 14个月宝宝o型腿怎么办 深蹲了三个月大腿变粗了怎么办 脚踢球时被踢肿了变紫了怎么办 没钱去健身房想要练出好身材怎么办 群里有人发反政府视频怎么办 部队取消番号后之前军人档案怎么办 新疆武警黄金部队新兵改革后怎么办 别人偷了自己的东西没有证据怎么办 家里项链被邻居偷了没有证据怎么办 知道是谁偷钱都是没有证据怎么办 武警驾照开地方车被交警拦了怎么办 双手擦了纤体瘦身膏辣疼怎么办 乳房全切术后切口裂开化脓怎么办 擦了锁水的霜之后出汗怎么办 用完瘦脸霜感觉脸部又痒又烧怎么办 嘴角起好多的小炮泡怎么办快好 DNF龙腾光环领错角色怎么办 海盗来了卡在新手奖励怎么办 海盗来了获得新手奖励卡了怎么办 魔域帐号忘了哪个区的了怎么办 魔域口袋版幻兽栏满了怎么办 苹果平板的密码和邮箱都忘了怎么办 二级报名忘了邮箱和密码怎么办 用身份证买的手机号变成空号怎么办 魔域口袋版背包幻兽满了怎么办? 魔域宝宝转世满了还不变雷怎么办 魔域口袋版家族试炼士气不足怎么办 聚水潭暂存位没有箱号怎么办? 长时间不锻炼运动后浑身酸痛怎么办 体脂称身体年龄比实际年龄大怎么办 分手两天我好难过好想去找他怎么办 宝宝一吃药就哭得很厉害怎么办