#include<absacc.h> 的用法 XBYTE介绍
(2013-04-29 13:48:26)
标签:
xbyte介绍xbyteinclude<absacc.h |
#include<absacc.h>
当51单片机通过8255和锁存器74LS273来扩展IO时,经常用到头文件absacc.h。在程序中,用“#include<absacc.h>”即可使用其中定义的宏来访问绝对地址,包括:CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD,例如:
rval=CBYTE[0x0002];指向程序存贮器的0002h地址
rval=XWORD [0x0002];指向外RAM的0004h地址
KEIL 中ABSACC.H 定义如下:
#ifndef __ABSACC_H__
#define __ABSACC_H__
#define CBYTE ((unsigned char
volatile code
#define DBYTE ((unsigned char
volatile data
#define PBYTE ((unsigned char volatile pdata *) 0)
#define XBYTE ((unsigned char volatile xdata *) 0)
#define CWORD ((unsigned int
volatile code
#define DWORD ((unsigned int
volatile data
#define PWORD ((unsigned int volatile pdata *) 0)
#define XWORD ((unsigned int volatile xdata *) 0)
#ifdef __CX51__
#define FVAR(object,
addr)
#define FARRAY(object, base) ((object volatile far *) (base))
#define FCVAR(object,
addr)
#define FCARRAY(object, base) ((object const far *) (base))
#else
#define FVAR(object,
addr)
#define FCVAR(object,
addr)
#define FARRAY(object,
base)
#define FCARRAY(object, base) ((object const far *) ((base)+0x810000L))
#endif
#endif
再如:
#define COM8255 XBYTE[0X060FF] //后面若出现COM8255,则单片机端口P0和P2联合输出0X060FF绝对物理地址(地址指向82C55指令寄存器)
#define PA8255 XBYTE[0X000FF] //后面若出现PA8255,则单片机端口P0和P2联合输出0X000FF绝对物理地址(地址指向82C55的A组端口寄存器)
#define PB8255 XBYTE[0X020FF] //后面若出现PB8255,则单片机端口P0和P2联合输出0X020FF绝对物理地址(地址指向82C55的B组端口寄存器)
#define PC8255 XBYTE[0X040FF] //后面若出现PC8255,则单片机端口P0和P2联合输出0X040FF绝对物理地址(地址指向82C55的C组端口寄存器)
absacc.h里的宏:
#define CBYTE ((unsigned char volatile
code
value = CBYTE[0x002];
这句该如何理解?
A1:结果是将程序空间(code)地址为0x002单元的内容放到变量value中。
A2:替换一下考虑:value = ((unsigned char volatile *) 0)[0x02];
替换一下考虑:unsigned char volatile *CBYTE = 0;
这里CBYTE[0x02] = 1和*(CBYTE+0x02) =
1等价
#define CBYTE ((unsigned char volatile
code
是把CBYTE是指针,即code地址0
在这里,数组和指针是可以互用的。CBYTE[0x02]也就是*(CBYTE+0x02),都是指的是地址0x02里的内容,并是unsig
ned char 类型的。
#define CBYTE ((unsigned char volatile
code
考虑下这个define定义的内容
1、把CBYTE定义成一个0(0);
2、这个0是个地址(*号);
3、这个地址是代码段的地址(code);
4、并是unsigned char类型的地址(unsigned char);
5、并这个地址的内容是易逝性的(volatile);
本质上是定义了一个地址(CBYTE )。指针就是地址,地址是内存的序号。
指针通过指向内存的序号访问内存,替换点是都是地址。
内部的括号用来强制类型转换用的,外部的的括号用来防止宏定义展开时错误的用法。
XBYTE是一个地址指针(可当成一个数组名或数组的首地址),它在文件absacc.h中由系统定义,指向外部RAM(包括I/O口)的0000H单元,XBYTE后面的中括号[
]0x2000H是指数组首地址0000H的偏移地址,即用XBYTE[0x2000]可访问偏移地址为0x2000的I/O端口。
XBYTE [0x4000] = 57;
这赋值语句,就可以把57写到外部RAM的0x4000处了,此地址对应一个字节。
XBYTE 的作用,可以用来定义绝对地址,是P0口和P2口的,其中P2口对应的是高位,P0口对应的是低位
如 XBYTE[0x1234] = 0x56;
则等价于
mov dptr,#1234h
mov @dptr,#56h
XBYTE的使用 收藏
XBYTE
The XBYTE macro accesses individual bytes in the external data memory of the 8051. You may use this macro in your programs as follows:
#include
.
.
.
rval = XBYTE [0x0002];
XBYTE [0x0002] = 57;
.
.
.This example reads and writes the contents of the byte in external data memory at address 0002h.
The range of valid index values for this macro is 0-65535.
http://www.keil.com/support/man/docs/c51/c51_xbyte.htm
XBYTE [0x4000] = 57。这赋值语句,就可以把57写到外部RAM的0x4000处了,此地址对应一个字节。
一下摘自论坛网友的问答:
问:
在一般的读写外部RAM的程序中,经常看到这样的句子:
但是我想问的是,为什么用了XBYTE后,就不用顾及其时序了呢?
就是说,读写数据的时候,WR和RD怎么都不用用程序去控制了呢?
参考了很多读写外部RAM的程序,都找不到其控制WR和RD控制线的语句
哪位大侠能帮忙解释一下这是为什么嘛?
最好还能说说XBYTE具体的用法.....
答:
外部总线,
1外部总线由3组总线组成,数据 地址 控制,我们常常一般就叫他外部总线,既然是有3组不同的信号,那么他们是怎么协调工作的呢?一般情况CPU有特殊的外部数据访问指令如你这里讲51的MOVX指令(在C语言中他会编译成这个指令)在执行这个指令的时候3组线是协调工作
mov dptr,#1000h
mov a,#55h
movx @dptr,a
上面3调语句的C语言可以表示如下
#define
W_DATA=0X55;
在使用外部总线的时候,数据 地址和控制信号是直接按照规定的时序输出高低电平的,所以不用你管,当然你必须要满足时序工作
一下摘自网友博客文章:
如何理解#define XBYTE ((unsigned char volatile xdata *
8051 特有的内存型态
code
data
idata
bdata
xdata
pdata
特殊资料型态
bit
sbit
语法
sbit
范例
sbit
或是配合 bdata 宣告的位(bit)变量
char
sbit
(注意 sbit 前不可以加 static)
sfr
语法
sfr
范例
sfr
指定绝对地址的变量
在单一模块内可以使用下面的语法宣告
[memory_space]
范例
pdata
如果该变量必须为多个模块所使用(Global Variable)则以
抽象指针(Abstract Pointer)的方式在标头档(Header File)定义较为方便。
#define
范例
#define
(注意 char 与 pdata 的顺序)
ABSACC.H 提供了下列方便的宏(Macro)定义。
#define CBYTE ((unsigned char volatile code *) 0)
#define DBYTE ((unsigned char volatile data *) 0)
#define PBYTE ((unsigned char volatile pdata *) 0)
#define XBYTE ((unsigned char volatile xdata *) 0)
#define CWORD ((unsigned int volatile code *) 0)
#define DWORD ((unsigned int volatile data *) 0)
#define PWORD ((unsigned int volatile pdata *) 0)
#define XWORD ((unsigned int volatile xdata *) 0)
隐藏的初始化程序
80C51 在电源重置后(Power On Reset)所执行的第一个程序模块并不是使用者的主程序
main(),而是一个隐藏在 KEIL-C51 标准链接库中称为 startup.a51 的程序模块。
startup.a51 的主要工作是把包含 idata、xdata、pdata 在内的内存区块清除为 0,并
且初始化递归指针。接着 startup.a51 被执行的仍然是一个隐藏在 KEIL-C51 标准链接库
中称为 init.a51 的程序模块。而 init.a51 的主要工作则是初始化具有非零初始值设定的
变量。
在完成上述的初始化程序之后,80C51 的控制权才会交给 main() 开始执行使用者的程序。
#define XBYTE ((unsigned char volatile xdata *) 0)
定义
这样,可以直接用XBYTE[0xnnnn]或*(XBYTE+0xnnnn)访问外部RAM了