Keil C51 xdata基址偏址寻址试验[转]

Keil C51 xdata基址偏址寻址试验[转]

(2009-11-18 22:18:31)
标签:

c51

基址

it

分类:软件技术

http://blog.sina.com.cn/s/blog_44153f8f0100eqsj.html

 

 本人最近用KEILC51来做一个程序,要用到外部数据存贮器,也要寻址外部别的芯片,因为要用到对外部数据的连续读写,因此对xdata做了一点详细研究。

   一、   第一种方式是定义外部对址常量,程序如下:

#defineXRAM       0x0000
#defineCYDRAM     0x1000
#defineEPM244H    0x4000
#defineEPM244L    0x5000

void readdata(unint add)

{

   volatileunchar xdata *xramadd;
  xramadd=CYDRAM+add; //just produce the CS signal of theCY7C024.
  rdata=*xramadd;
   _nop_();
  xramadd=EPM244H;
  rdatah=*xramadd;
  xramadd=EPM244L;
  rdatal=*xramadd;

}

void main()

{

       readdata(0x0002);

}

上面程序可以比较灵活的读出自0x1000以后的地址,直要在后面加上所要读出的偏址add就可,主程序中的调用,则此时返回0x1002的数据。在子程序中要定义一个xramadd的指针,让要求的地址指向它。注意要加volatile,这样在你连读的情况下,不被编程器优化。

二、另外一个情况就是使用_at_指令,这种方式我认为不够灵活,要是连续读写多个数据,就要定义一个数组,势必没有指针灵活,程序如下:

volatile unchar xdataSCYDRAM   _at_0x1000;
volatile unchar xdataSEPM244H   _at_0x4000;
volatile unchar xdataSEPM244L   _at_0x5000;

void readdata(unint add)

{

  rdata=SCYDRAM+add;  //just produce the CS signal of the CY7C024.
  rdatah=SEPM244H;
  rdatal=SEPM244L;

}

void main()

{

       readdata(0x0002);

}

这样得到的结果是不正确的,编译器并没有按要求在0x1002的地方寻址,而是在0x1000的地方寻址,怎么解决这个问题呢?那就是定义一个数组,volatile unchar xdataSCYDRAM[256]   _at_0x1000;只有这样,通过数组来调用,才能够得到相应的结果。程序如下:

void readdata(unchar add)

{

  rdata=SCYDRAM[add];  //just make the CS signal of the CY7C024.
  rdatah=SEPM244H;
  rdatal=SEPM244L;

}

void main()

{

       readdata(0x02);

}

这样读出的数据是正确的。

三、可以使用XBYTE来定义,但是要包括#include<absacc.h>此文件。如下。

#include <absacc.h>

#defineSCYDRAM  XBYTE[0x1000];
#define SEPM244H  XBYTE[0x4000];
#define SEPM244L  XBYTE[0x5000];

我认为其和_at_指令的做法是一样的。但是灵活性更差。还不能定义数组。只能是单地址寻址,这种也是主要用在对外部固定地址寻址之用,比如8255,373,AD转换器等。要连续寻址最好用第一种方法,第二种定义一个数组也是可以的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值