1、 char *addr=0xc000; char xdata *addr=0xc000; 除了在内存中占用的字节不同外,还有别的区别吗? char *addr=0xc000; 是通用定义,指针变量 addr 可指向任何内存空间的值; char xdata *addr=0xc000; 指定该指针变量只能指向 xdata 中的值; 后一种定义中该指针变量(addr)将少占用一个存储字节。 uchar xdata *addr=0xc000;指针指向外ram; 如果:data uchar xdata *addr=0xc000;指针指向外ram但指针本身存在于内
2、ram(data) 中 以此类推可以idata uchar xdata *addr=0xc000;pdata uchar xdata *addr=0xc000; data uchar idata *addr=0xa0;......... 51C语言能不能定义1024个字节的xdata unsigned char的数组呢? 电路是用hc573和6264外扩了8K的ram 需要定义1024个字节的xdata unsigned char的数组,然后写了个测试程序测试定义的数组是否正常 FillMemory(RecBuffer,MAXCOMMBUFFER
3、SIZE-1,0x12);//先填充RecBuffer为0x12 for(i=0;i 4、FF(255)
单片机C语言教程-指针基础知识
一. 指针变量的定义
指针变量定义与一般变量的定义类似,其形式如下:
数据类型 [存储器类型1] * [存储器类型2] 标识符;
[存储器类型1] 表示被定义为基于存储器的指针,无此选项时,被定义为一般指针。这两种指针的区别在于它们的存储字节不同。一般指针在内存中占用三个字节,第一个字节存放该指针存储器类型的编码(由编译时由编译模式的默认值确定),第二和第三字节分别存放该指针的高位和低位地址偏移量。存储器类型的编码值如下:
存储类型I
Idata/data/bdata
xdata
pdata
Code
编码值
0x 5、00
0x01
0xFE
0xFF
[存储类型2]用于指定指针本身的存储器空间。
1. char * c_ptr; int * i_ptr; long * l_ptr;
上述定义的是一般指针,c_ptr指向的是一个char型变量,那么这个char型变量位于哪里呢?这和编译时由编译模式的默认值有关,
如果Menory Model—Variable—Large:XDATA,那么这个char型变量位于xdata区:
如果Menory Model—Variable—Compact:PDATA, 那么这个char型变量位于pdata 区:
如果Menory Model——Variab 6、le——Small:DATA,那么这个char型变量位于data区。
而指针c_ptr, i_ptr, l_ptr变量本身位于片内数据存储区中。
2. char * data c_ptr; int * idata i_ptr; long * xdata l_ptr;
上述定义,c_ptr, i_ptr, l_ptr变量本身分别位于data ,idata,xdata区。
3. char data * c_ptr; //表示指向的是data区中的char型变量,c_ptr在片内存储区中;
int xdata * i_ptr; //表示指向的是xdata区中的int型变量,i_pt 7、r在片内存储区中;
long code * l_ptr; //表示指向的是code区中的long型变量,l_ptr在片内存储区中;
4. char data * data c_ptr; //表示指向的是data区中的char型变量,c_ptr在片内存储区data中;
Int xdata * idata i_ptr; //表示指向的是xdata区中的int型变量,i_ptr在片外存储区xdata中;
long code * xdata l_ptr; //表示指向的是code区中的long型变量,l_ptr在片内存储区xdata中;
二. 指针应用
1. int x, j;
8、int * px, *py;
px=&x; py=&y;
2. *px=0; py=px;
3. *px++<=>*(px++)
4. (*px)++<=>x++
5. unsigned char xdata * x;
unsinged char xdata * y;
x=0x0456;
*x=0x34 //等价于 mov dptr,#456h ; mov a,#34h; movx @dptr,a
6. unsigned char pdata * x;
x=0x045;
*x=0x34 //等价于 mov r0,#45h ; mov a,#34h; m 9、ovx @r0,a
7. unsigned char data * x;
x=0x30;
*x=0x34 //等价于 mov a,#34h; mov 30h ,a
8. int *px;
px=(int xdata *)0x4000; //将 xdata 型指针 0x4000 赋给 px,也就是将0x4000强制转换为指向xdata区中的int型变量的指针,将其赋给px。
9. int x;
x=*((char xdata *)0x4000); //将0x4000强制转换为指向xdata区中的int型变量的指针,从这个地址中取出值赋给变量x。
10. px=*( 10、int xdata * xdata *)0x4000); //如何分析?
11. px=*((int xdata * xdata *)0x4000);将阴影部分遮盖,这个意思就是将0x4000强制转换为指向xdata区中的X型变量的指针,这个X型变量就是阴影“int xdata *”,也就是0x4000指向的变量类型是一个指向xdata区中的int型变量的指针,即0x4000中放的是另外一个指针,这个指针指向的是xdata区中的int型变量。Px值放的是0x4000中放的那个指针。比如【0x4000】—【0x2000】-0x34。Px=0x2000。
12. x=**((int 11、xdata * xdata *)0x4000); x中放着0x4000中放的那个指针所指向的值。比如【0x4000】—【0x2000】-0x34。
三. 指针与数组
1. int arr[10];
int * pr;
pr=arr; // 等价于pr=&arr[0];
这样的话,*(pr+1)==arr[1]; *(pr+2)==arr[2]; *(arr+3)==arr[3]; *(arr+4)==arr[4];
或者 pr[0],pr[1]….代表 arr[0],arr[1]…..
可以*pr++ (等价于*(pr++)),来访问所有数组元素,而*arr++是不行的。因为 12、arr是常量,不能++运算
2. char * s1
char code str[]=”abcdefg”
s1=str;
3. char *s1=”abcdefg”;
四. 指针与结构体
1. typedef struct _data_str {
unsigned int DATA1[10];
unsigned int DATA2[10];
unsigned int DATA3[10];
unsigned int DATA4[10];
unsigned int DATA5[10];
unsigned int DATA6[10];
unsigned int D 13、ATA7[10];
unsigned int DATA8[10];
}DATA_STR;
//开辟一个外RAM空间,确保这个空间够装你所需要的
xdata uchar my_data[MAX_STR] _at_ 0x0000;
DATA_STR *My_Str;
My_Str=(DATA_STR*)my_data; //把你的结构体指针指向这个数组的开头
以后的操作就这样:
My_Str->DATA1[0]=xxx;
My_Str->DATA1[1]=xxx;
那么你的变量就自然放到XDATA中去了.
注意定义的my_data[MAX_STR],不能随便被操作,它只是开始 14、的时候用来开辟内存用的.
2. struct student
{
char name[20];
int num;
}stu1,stu2;
3. struct student
{
char name[20];
int num;
};
struct student stu1,stu2;
struct student *p;
p=&stu1;
访问成员方法:
A. stu1.num
B. (*p).num; //因为“.”的优先级高于“*”所以要加括号。
C. P->num;
4. struct student stu[10];
struct stu 15、dent * p;
p=stu;
(责任编辑:admin) 1. 使用指针
采用指针的方法,可实现在C51程序中对任意指定的存储器地址进行操作。例如:
#define uchar unsigned char
#define uint unsigned int
void test_memory(void) {
uchar idata ivar1;
uchar xdata *xdp; /*定义一个指向XDATA存储器空间的指针*/
char data *dp; /*定义一个指向DATA存储器空间的指针*/
uc 16、har idata *idp; /*定义一个指向IDATA存储器空间的指针*/
xdp=0x1000; /*XDATA指针赋值,指向XDATA存储器地址1000H处*/
*xdp=0x5A; /*将数据5AH送到XDATA的1000H单元*/
dp=0x61; /*DATA指针赋值,指向DATA存储器地址61H处*/
*dp=0x23; /*将数据23H送到DATA的61H单元*/
idp=&ivar1; /*idp指向IDATA区变量ivar 17、1*/
*idp=0x16; /*等价于ivar1=0x16*/
}
2. 使用C51运行库中预定义宏
C51编译器提供了一组宏定义用来对80C51系列单片机的CODE、DATA、PDATA和XDATA空间进行绝对地址访问。函数原型如下:
#define CBYTE((unsigned char volatile *)0x50000L)
#define DBYTE((unsigned char volatile *)0x40000L)
#define PBYTE((unsigned char volatile *)0x30000L)
#define X 18、BYTE((unsigned char volatile *)0x20000L)
#define CWORD((unsigned int volatile *)0x50000L)
#define DWORD((unsigned int volatile *)0x40000L)
#define PWORD((unsigned int volatile *)0x30000L)
#define XWORD((unsigned int volatile *)0x20000L)
这些函数原型放在absacc.h文件中。
CBYTE以字节形式对CODE区寻址,DBYTE以字节形式对DAT 19、A区寻址,PBYTE以字节形式对PDATA区寻址,XBYTE以字节形式对XDATA区寻址,CWORD以字形式对CODE区寻址,DWORD以字形式对DATA区寻址,PWORD以字形式对PDATA区寻址,XWORD以字形式对XDATA区寻址。例如:
#include 20、 XWORD [0x0002]; /*访问外部 RAM 0004H~0005H地址的内容*/
uc_var1 = XBYTE [0x0002]; /*访问外部 RAM 0002H地址的内容*/
……
while(1);
}
需要注意的是,ui_var1在外部存储器区访问0x0004。通过使用#define预处理器命令,可采用其他符号定义绝对地址。
3. 使用C51扩展关键字 _at_
使用_at_对指定的存储器空间的绝对地址进行定位,一般格式如下:
[存储器类型] 数据类型 标识符 _at_ 常数
其中,存储器 21、类型为idata、data、xdata等C51能识别的数据类型,如果省略该选项,则按编译模式SMALL、COMPAC或TLARGE规定的默认存储器类型确定变量的存储器空间;数据类型除了可用int、long、float等基本类型外,还可采用数组、结构等复杂数据类型;常数规定变量的绝对地址,必须位于有效的存储器空间之内;使用_at_定义的变量只能为全局变量。例如:
uchar xdata xram[0x8000] _at_ 0x0000; /*在外部RAM空间0000H处定义了一个一维数组
变量xram,数组的元素个数为32768(0x8000)*/
struct bir 22、thdate{
int year;
uchar month, day;
}
idata struct birthdate Hans _at_ 0x60; /*结构变量Hans定位于IDATA空间地址0x60 */
5.5.5 中断服务程序
80C51的中断系统十分重要,C51编译器允许在C语言源程序中声明中断和编写中断服务程序,从而减轻了采用汇编程序编写中断服务程序的繁琐程度。通过使用interrupt关键字来实现。定义中断服务程序的一般格式如下:
void 函数名( ) interrupt n [using m]
关键字i 23、nterrupt后面的n是中断号,n的取值范围:0~31。编译程序从8n+3处产生中断向量,即在程序存储器8n+3地址处形成一条长跳转指令,转向中断号n的中断服务程序。中断号对应着IE寄存器中的使能位,即:IE寄存器中的0位对应着外部中断0,相应的外部中断0的中断号是0。中断号0~4对应中断源的关系如表所示。
中断号和中断源的对应关系
using m指明该中断服务程序所对应的工作寄存器组,取值范围:0~3。指定工作寄存器组的缺点是所有被中断调用的过程都必须使用同一个寄存器组,否则参数传递会发生错误。通常不设定using m,除非保证中断程序中未调用其他子程序。
使用C51 24、编写中断服务程序,程序员无需关心ACC、B、DPH、DPL、PSW等寄存器的保护,C51编译器会根据上述寄存器的使用情况在目标代码中自动增加压栈和出栈。
C51具有ANSI C的所有标准数据类型。
其基本数据类型包括:char、int、short、long、float和double,对C51编译器来说,short类型和int类型相同,double类型和float类型相同。整型和长整型的符号位字节在最低的地址中。
除此之外,为了更加有利地利用80C51的结构,C51还增加了一些特殊的数据类型,包括bit、sfr、sfr16、sbit。
1. char字符类型
char类型的长度是1B, 25、通常用于定义处理字符数据的变量或常量。分无符号字符类型unsigned char和有符号字符类型signed char,默认值为signed char类型。unsigned char类型用字节中所有的位表示数值,可以表达的数值范围是0~255。signed char类型用字节中最高位表示数据的符号,0表示正数,1表示负数,负数用补码表示,能表示的数值范围是-128~+127。unsigned char常用于处理ASCII字符或用于处理小于或等于255的整型数。
正二进制数的补码与原码相同,负二进制数的补码等于它的绝对值按位取反后加1。
2. int整型
int整型长度为2B,用于存放一 26、个双字节数据。分有符号int整型数signed int和无符号int整型数unsigned int,默认值为signed int类型。signed int表示的数值范围是-32768~+32767,字节中最高位表示数据的符号,0表示正数,1表示负数。unsigned int表示的数值范围是0~65535。
3. long长整型
long长整型长度为4B,用于存放一个4B数据。分有符号long长整型signed long和无符号long长整型unsigned long,默认值为signed long类型。signed int表示的数值范围是-2147483648~+2147483647,字节 27、中最高位表示数据的符号,0表示正数,1表示负数。unsigned long表示的数值范围是0~4294967295。
4. float浮点型
float浮点型在十进制中具有7位有效数字,是符合IEEE-754标准(32)的单精度浮点型数据,占用4B。具有24位精度。
5. *指针型
指针型本身就是一个变量,在这个变量中存放的指向另一个数据的地址。这个指针变量要占据一定的内存单元,对不同的处理器长度也不尽相同,在C51中它的长度一般为1~3个字节。
6. bit位标量
bit位标量是C51编译器的一种扩充数据类型,利用它可定义一个位标量,但不能定义位指针,也不能定义位数组。它的值是一 28、个二进制位,不是0,就是1,类似一些高级语言中的Boolean类型中的True和False。
7. sfr特殊功能寄存器
sfr也是一种扩充数据类型,点用一个内存单元,值域为0~255。利用它可以访问51单片机内部的所有特殊功能寄存器。如用sfr P1 = 0x90这一句定义P1为P1端口在片内的寄存器,在后面的语句中可以用P1 = 255(对P1端口的所有引脚置高电平)之类的语句操作特殊功能寄存器。
8. sfr16 16位特殊功能寄存器
sfr16用于定义存在于80C51单片机内部RAM的16位特殊功能寄存器。sfr16型数据占用2个内存单元,取值范围为0~65535,如定时器T 29、0和T1。通过名字或地址引用的sfr16地址必须大于80H。
9. sbit可寻址位
sbit同位是C51中的一种扩充数据类型,利用它可以访问芯片内部的RAM中的可寻址位或特殊功能寄存器中的可寻址位。
在80C51单片机系统中,经常要访问特殊功能寄存器中的某些位,用关键字sbit定义可位寻址的特殊功能寄存器的位寻址对象。
定义方法有如下三种:
(1)sbit 位变量名 = 位地址
将位的绝对地址赋给位变量,位地址必须位于0x80H~0xFF之间。
(2)sbit 位变量名 = 特殊功能寄存器名^位位置
当可寻址位位于特殊功能寄存器中时,可采用这种方法。位位置是一个0~7之间的常 30、数。
(3)sbit 位变量名 = 字节地址^位位置
这种方法是以一个常数(字节地址)作为基地址,该常数必须在0x80H~0xFF之间。位位置是一个0~7之间的常数。
80C51单片机中的特殊功能寄存器和特殊功能寄存器可寻址位,已被预先定义放在文件reg51.h中,在程序的开头只需加上#include 31、特殊功能寄存器中的可寻址位;而bit则定义了一个普通的位变量,一个函数中可包含bit类型的参数,函数返回值也可为bit类型。
5.5.3 变量的存储种类和存储器类型
变量是一种在程序执行过程中,其数值不断变化的量。C51规定变量必须先定义后使用。C51对变量的进行定义的格式如下:
[存储种类] 数据类型 [存储器类型] 变量名表
其中,存储种类和存储器类型是可选项。
1. 存储种类
存储种类是指变量在程序执行过程中的作用范围。变量的存储种类有四种,分别为:自动(auto)、外部(extern)、静态(static)和寄存器(register)。
使用存储种类说明符auto定义的 32、变量称为自动变量。
自动变量作用范围在定义它的函数体或复合语句内部,在定义它的函数体或复合语句被执行时,C51才为该变量分配内存空间,当函数调用结束返回或复合语句执行结束时,自动变量所占用的内存空间被释放,这些内存空间又可被其他的函数体或复合语句使用。可见使用自动变量能最有效地使用80C51单片机内存。定义变量时,如果省略存储种类,则该变量默认为自动(auto)变量。
由于80C51单片机访问片内RAM速度最快,通常将函数体内和复合语句中使用频繁的变量放在片内RAM中,且定义为自动变量,可有效地利用片内有限的RAM资源。
使用外部种类存储符extern定义的变量称为外部变量。
在一个函 33、数体内,要使用一个已在该函数体外或别的程序模块文件中定义过的外部变量时,该变量在本函数体内要用extern说明。外部变量被定义后,即分配了固定的内存空间,在程序的整个执行时间内都是有效的。通常将多个函数或模块共享的变量定义为外部变量。外部变量是全局变量,在程序执行期间一直占有固定的内存空间。当片内RAM资源紧张时,不建议将外部变量放在片内RAM。
使用存储种类说明符static定义的变量称为静态变量。
静态变量分为局部静态变量和全局静态变量。
局部静态变量是在两次函数调用之间仍能保持其值的局部变量。有些程序要求在多次调用之间仍然保持变量的值,使用自动变量无法作用到这一点。使用全局变量有时 34、会带来意外的副作用,这时可采用局部静态变量。
使用存储种类说明符register定义的变量称为寄存器变量。
80C51访问寄存器的速度最快,通常将使用频率最高的那些变量定义为寄存器变量。C51编译器能自动识别程序中使用频率最高的变量,并自动将其作为寄存器变量,用户无需专门声明。
2. 存储器类型
定义变量时,除了说明存储种类外,还允许说明变量的存储器类型。存储器类型和存储种类是完全不同的概念,存储器类型指明该变量所处的单片机的内存空间。
如果在变量定义时省略了存储器类型标识符,C51编译器会选择默认的存储器类型。默认的存储器类型由SMALL、COMPACT和LARGE存储模式指 35、令决定。
1)DATA区
对DATA区的寻址是最快的,所以应该把使用频率高的变量放在DATA区,由于空间有限,必须注意使用DATA区,DATA区除了包含程序变量外,还包含了堆栈和寄存器组DATA区。
unsigned char data system_status=0;
unsigned int data unit_id[2];
char data inp_string[16];
float data outp_value;
mytype data new_var;
在SMALL存储模式下,未说明存储器类型时,变量默认被定位在DATA区。标准变量和用户自定义变量都可以存储 36、在DATA区,只要不超过DATA区的范围。因为C51使用默认的寄存器组传递参数,至少失去了8B。另外要定义足够大的堆栈空间,当内部堆栈溢出的时候,程序会产生莫名其妙的错误,实际原因是80C51系列单片机没有硬件报错机制,堆栈溢出只能以这种方式表示出来。
2)BDATA区
当在DATA区的位寻址区定义变量,这个变量就可进行位寻址,并且声明位变量。这对状态寄存器来说十分有用,因为它可以单独使用变量的每一位,而不一定要用位变量名引用位变量。下面是一些在BDATA区中声明变量和使用位变量的例子。
unsigned char bdata status_byte;
unsigned int bda 37、ta status_word;
unsigned long bdata status_dword;
sbit stat_flag=status_byte^4;
if(status_word^15){
……}
stat_flag=1;
编译器不允许在BDATA区中定义float和double类型的变量,如果想对浮点数的每位寻址,可以通过包含float和long的联合实现。
typedef union{ /*定义联合类型*/
unsigned long lvalue; /*长整型3 38、2位*/
float fvalue; /*浮点数32位*/
}bit_float; /*联合名*/
bit_float bdata myfloat; /*在BDATA区中声明联合*/
sbit float_ld=myfloat.lvalue^31; /*定义位变量名*/
3)IDATA区
IDATA区也可以存放使用比较频繁的变量,使用寄存器作为指针进行寻址。在寄存器中设置8位地址进行间接寻址,与外 39、部存储器寻址比较,它的指令执行周期和代码长度都比较短。
unsigned char idata system_status=0;
unsigned int idata unit_id[2];
char idata inp_string[16];
float idata outp_value;
4)PDATA和XDATA区
在这两个区声明变量和在其他区的语法是一样的,PDATA区只有256B,而XDATA区可达65536B,举例如下。
unsigned char xdata system_status=0;
unsigned int pdata unit_id[2];
char 40、 xdata inp_string[16];
float pdata outp_value;
对PDATA和XDATA的操作是相似的,对PDATA区寻址比对XDATA区寻址要快,因为对PDATA区寻址只需要装入8位地址,而对XDATA区寻址需装入16位地址。所以尽量把外部数据存储在PDATA区中,对PDATA和XDATA寻址要使用MOVX指令,需要2个处理周期。
5)CODE区
CODE区即80C51的程序代码区,所以代码区的数据是不可改变的,80C51的代码区不可重写。一般代码区中可存放数据表,跳转向量和状态表,对CODE区的访问和对XDATA区的访问的时间是一样的,代码区中的对象在 41、编译时初始化,否则就得不到想要的值。下面是代码区的声明例子。
unsigned int code unit_id[2]={0x1234, 0x89ab};
unsigned char code uchar_data[16] ={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15};
3. 存储模式
C51编译器允许采用三种存储模式:小编译模式SMALL、紧凑编译模式COMPACT、大编译模式LARGE。一个变量的存储器模式确定了变量在内存中的地址空间。在SMALL模式下,该变 42、量在80C51单片机的内部RAM中;在COMPACT和LARGE模式下,该变量在80C51单片机的外部RAM中。同样一个函数的存储器模式确定了函数的参数和局部变量在内存中的地址空间。在SMALL模式下,函数的参数和局部变量在80C51单片机的内部RAM中;在COMPACT和LARGE模式下,函数的参数和局部变量在80C51单片机的外部RAM中。
下面这个例子说明了存储模式的定义方法。
【例5.15】 变量和函数的存储模式
#pragma small /*默认存储器类型为80C51片内直接寻址RAM*/
char data i,j,k; 43、 /*在80C51片内直接寻址RAM中定义了3个变量,默认为自
动变量*/
char i,j,k; /*未指明存储模式,由#pragma small决定,与前一句完全等价*/
int xdata m, n; /*在80C51片外RAM中定义了2个自动变量*/
static char m, n; /*在80C51片内直接寻址RAM中定义了2个静态变量*/
unsigned ch 44、ar xdata ram[128]; /*在80C51片外RAM中定义了大小为128B的数组变量*/
int func1(int i, int j) large /*指定 large 模式*/
{
return(i+j);
}
int func2(int i, int j) /*未指明存储模式, 按默认的SMALL模式*/
{
return(i-j);
}
不同的存储器类型访问速度是不一样的,如:
unsigned char data var1; / 45、SMALL模式,var1被定位在DATA区*/
/*即80C51片内直接寻址RAM*/
unsigned char pdata var1; /*COMPACT模式,var1被定位在PDATA区*/
/*即80C51片外按页面间接寻址RAM*/
unsigned char xdata var1; /*LARGE模 46、式,var1被定位在XDATA区*/
/*即80C51片外间接寻址RAM*/
在SMALL模式下,var1被定位在DATA区,经C51编译器编译后,采用内部RAM直接寻址方式访问速度最快;在COMPACT模式下,var1被定位在PDATA区,经C51编译器编译后,采用外部RAM间接寻址方式访问速度较快;在LARGE模式下,var1被定位在XDATA区,经C51编译器编译后,采用外部RAM间接寻址方式访问速度最慢。为了提高系统运行速度,建议在编写源程序时,把存储模式设定为SMALL 47、再在程序中把XDATA、PDATA和IDATA等类型变量进行专门声明。
5.5.4 绝对地址的访问
1. 使用指针
采用指针的方法,可实现在C51程序中对任意指定的存储器地址进行操作。例如:
#define uchar unsigned char
#define uint unsigned int
void test_memory(void) {
uchar idata ivar1;
uchar xdata *xdp; /*定义一个指向XDATA存储器空间的指针*/
char data *dp; /*定义一 48、个指向DATA存储器空间的指针*/
uchar idata *idp; /*定义一个指向IDATA存储器空间的指针*/
xdp=0x1000; /*XDATA指针赋值,指向XDATA存储器地址1000H处*/
*xdp=0x5A; /*将数据5AH送到XDATA的1000H单元*/
dp=0x61; /*DATA指针赋值,指向DATA存储器地址61H处*/
*dp=0x23; /*将数据23H送到DATA的61H单元*/
idp=&ivar1; 49、 /*idp指向IDATA区变量ivar1*/
*idp=0x16; /*等价于ivar1=0x16*/
}
2. 使用C51运行库中预定义宏
C51编译器提供了一组宏定义用来对80C51系列单片机的CODE、DATA、PDATA和XDATA空间进行绝对地址访问。函数原型如下:
#define CBYTE((unsigned char volatile *)0x50000L)
#define DBYTE((unsigned char volatile *)0x40000L)
#define PBYTE((unsigned char volatile * 50、)0x30000L)
#define XBYTE((unsigned char volatile *)0x20000L)
#define CWORD((unsigned int volatile *)0x50000L)
#define DWORD((unsigned int volatile *)0x40000L)
#define PWORD((unsigned int volatile *)0x30000L)
#define XWORD((unsigned int volatile *)0x20000L)
这些函数原型放在absacc.h文件中。
CBYTE以字节形式对C






