#includeabsacc.h 的⽤法 XBYTE介绍
#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  *) 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)
#ifdef __CX51__
#define FVAR(object, addr)  (*((object volatile far *) (addr)))
#define FARRAY(object, base) ((object volatile far *) (base))
#define FCVAR(object, addr)  (*((object const far *) (addr)))
#define FCARRAY(object, base) ((object const far *) (base))
#else
#define FVAR(object, addr)    (*((object volatile far *) ((addr)+0x10000L)))
#define FCVAR(object, addr)  (*((object const far *) ((addr)+0x810000L)))
#define FARRAY(object, base)  ((object volatile far *) ((base)+0x10000L))
#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  *) 0)
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  *) 0)
是把CBYTE是指针,即code地址0
在这⾥,数组和指针是可以互⽤的。CBYTE[0x02]也就是*(CBYTE+0x02),都是指的是地址0x02⾥的内容,并是unsig ned char 类型的。
#define CBYTE ((unsigned char volatile code  *) 0)
考虑下这个define定义的内容
include怎么用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端⼝。
这个主要是在⽤C51的P0,P2⼝做外部扩展时使⽤,其中XBYTE [0x0002],P2⼝对应于地址⾼位,P0⼝对应于地址低位。⼀般P2⼝⽤于控制信号,P0⼝作为数据通道。
⽐如:P2.7接WR,P2.6接RD,P2.5接CS,那么就可以确定个外部RAM的⼀个地址,想往外部RAM的⼀个地址写⼀个字节时,地址可以定为XBYTE [0x4000],其中WR,CS为低,RD为⾼,那就是⾼位的4,当然其余的可以根据情况⾃⼰定,然后通过
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.
www.keil/support/man/docs/c51/c51_xbyte.htm
上⾯的是在keil的help⾥ctrl+c来的,以前在论坛⾥看到过有⼈问如何⽤c语⾔实现定位存储,呵呵,当时还说不可能呢!现在在查using的时候,⽆意中看到了XBYTE,点中看看,居然有⼤发现啊!
百度结果:这个主要是在⽤C51的P0,P2⼝做外部扩展时使⽤,其中XBYTE [0x0002],P2⼝对应于地址⾼位,P0⼝对应于地址低位。⼀般P2⼝⽤于控制信号,P0⼝作为数据通道。
如:P2.7接WR,P2.6接RD,P2.5接CS,那么就可以确定个外部RAM的⼀个地址,想往外部RAM的⼀
个地址写⼀个字节时,地址可以定为XBYTE [0x4000],其中WR,CS为低,RD为⾼,那就是⾼位的4,当然其余的可以根据情况⾃⼰定,然后通过
XBYTE [0x4000] = 57。这赋值语句,就可以把57写到外部RAM的0x4000处了,此地址对应⼀个字节。
⼀下摘⾃论坛⽹友的问答:
问:
在⼀般的读写外部RAM的程序中,经常看到这样的句⼦:
XBYTE[address]=data  写数据
data=XBYTE[address]  读数据
但是我想问的是,为什么⽤了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  XBYTE[0x1000]
W_DATA=0X55;
在使⽤外部总线的时候,数据 地址和控制信号是直接按照规定的时序输出⾼低电平的,所以不⽤你管,当然你必须要满⾜时序⼯作
⼀下摘⾃⽹友博客⽂章:
如何理解#define XBYTE ((unsigned char volatile xdata *
8051 特有的内存型态
code    以 MOVC @A+DPTR 读取的程序内存
data    可以直接存取的内部数据存储器
idata    以 Mov @Rn 存取的内部数据存储器
bdata    可以位寻址(Bit Addressable)的内部存储器
xdata    以 MOVX @DPTR 存取的外部数据存储器
pdata    以 MOVX @Rn 存取的外部数据存储器
特殊资料型态
bit    ⼀般位(bit)变量
sbit    绝对寻址的位(bit)变量
语法
sbit    my_flag    =    location;    (location 范围从 0x00 ~ 0x7F)
范例
sbit    EA =    0xAF;
或是配合 bdata 宣告的位(bit)变量
char    bdata        my_flags;
sbit    flag0 =      my_flags ^ 0;
(注意 sbit 前不可以加 static)
sfr    特殊功能缓存器(Special Function Register)
语法
sfr    my_sfr    =    location;    (location 范围从 0x80 ~ 0xFF)
范例
sfr    P0    =    0x80;
指定绝对地址的变量
在单⼀模块内可以使⽤下⾯的语法宣告
[memory_space]    type    variable_name    _at_    location
范例
pdata        char    my_pdata    _at_    0x80;
如果该变量必须为多个模块所使⽤(Global Variable)则以
抽象指针(Abstract Pointer)的⽅式在标头档(Header File)定义较为⽅便。
#define    variable_name    *((data_type *)        location)
范例
#define    my_pdata    *((char pdata *)    0x80)
(注意 char 与 pdata 的顺序)
ABSACC.H 提供了下列⽅便的宏(Macro)定义。
#define CBYTE ((unsigned char volatile code *) 0)
#define DBYTE ((unsigned char volatile data *) 0)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。