Keil C51 xdata基址偏址寻址试验
一、 第一种方式是定义外部对址常量,程序如下:
#define XRAM 0x0000
#define CYDRAM 0x1000
#define EPM244H 0x4000
#define EPM244L 0x5000
void readdata(unint add)
{
volatile unchar xdata *xramadd;
xramadd=CYDRAM+add; //justproduce the CS signal of the CY7C024.
rdata=*xramadd;
_nop_();
xramadd=EPM244H;
rdatah=*xramadd;
xramadd=EPM244L;
rdatal=*xramadd;
}
void main()
{
readdata(0x0002);
}
上面程序可以比较灵活的读出自0x1000以后的地址,直要在后面加上所要读出的偏址add就可,主程序中的调用,则此时返回0x1002的数据。在子程序中要定义一个xramadd的指针,让要求的地址指向它。注意要加volatile,这样在你连读的情况下,不被编程器优化。
二、另外一个情况就是使用_at_指令,这种方式我认为不够灵活,要是连续读写多个数据,就要定义一个数组,势必没有指针灵活,程序如下:
volatile unchar xdata SCYDRAM _at_ 0x1000;
volatile unchar xdata SEPM244H _at_ 0x4000;
volatile unchar xdata SEPM244L _at_ 0x5000;
void readdata(unint add)
{
rdata=SCYDRAM+add; //justproduce the CS signal of the CY7C024.
rdatah=SEPM244H;
rdatal=SEPM244L;
}
void main()
{
readdata(0x0002);
}
这样得到的结果是不正确的,编译器并没有按要求在0x1002的地方寻址,而是在0x1000的地方寻址,怎么解决这个问题呢?那就是定义一个数组,volatile unchar xdata SCYDRAM[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 此文件。如下。
#include
#define SCYDRAM XBYTE[0x1000];
#define SEPM244H XBYTE[0x4000];
#define SEPM244L XBYTE[0x5000];
我认为其和_at_指令的做法是一样的。但是灵活性更差。还不能定义数组。只能是单地址寻址,这种也是主要用在对外部固定地址寻址之用,比如8255,373,AD转换器等。要连续寻址最好用第一种方法,第二种定义一个数组也是可以的。
四、这里写的只是我的一点调试总结,可能有很多理解不对的地方,请大家指正。
KeilC51xdata基址偏址寻址试 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)