51访问绝对地址

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#define CBYTE((unsigned char volatile *)0x50000L)
#define DBYTE((unsigned char volatile *)0x40000L)
#define PBYTE((unsigned char volatile *)0x30000L)
#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)))
注意:不能对变量进行初始化,只能是全局变量,一般不要轻易用,免得出错。
举例:
xdata unsigned int文件absacc.h,也不是很难,举个例说明一下就会明白:
#include <absacc.h>
采用指针的方法,可实现在C51程序中对任意指定的存储器地址进行操作。例如:
#define uchar unsigned char
#define uint unsigned int
void test_memory(void) {
uchar xdata xram[0x8000] _at_ 0x0000;
struct birthdate{
int year;
uchar month, day;
}
idata struct birthdate Hans _at_ 0x60;
51单片机C语言学习笔记4:
keil C51绝对地址访问:
在利用keil进行8051单片机编程的时,常常需要进行绝对地址进行访问.特
别是对硬件操作,如DA AD 采样 ,LCD 液晶操作,打印操作.等等.
#include<absacc.h>
#define ADstart XBYTE[0x8000] //总线方式访问AD
#define ADL XBYTE[0x8000]
#define ADH XBYTE[0x8001]
rval=CBYTE[0x0002];指向程序存贮器的0002h地址
All rights reserved.
------------------------------------------------*/
#ifndef __ABSACC_H__
#define __ABSACC_H__
#define CBYTE ((unsigned char volatile code *) 0)
关键字interrupt
后面的n是中断号,n的取值范围:0~31。编译程序从8n+3处产生中断向量,即在程序存储器8n+3地址处形成一条长跳转指令,转向中断号n的中断服务程序。中断号对应着IE寄存器中的使能位,即:IE寄存器中的0位对应着外部中断0,相应的外部中断0的中断号是0。中断号0~4对应中断源的关系如表所示。
C51提供了三种访问绝对地址的方法:
1. 绝对宏:
在程序中,用“#include<absacc.h>”即可使用其中定义的宏来访问绝对地址,包括:CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD
具体使用可看一看absacc.h便知
例如:
#define XBYTE((unsigned char volatile *)0x20000L)
#define CWORD((unsigned int volatile *)0x50000L)
#define DWORD((unsigned int volatile *)0x40000L)
#define PWORD((unsigned int volatile *)0x30000L)
在进行8051单片机应用系统程序设计时,编程都往往少不了要直接操作系统的各个存储器地址空间。C51程序经过编译之后产生的目标代码具有浮动地址,其绝对地址必须经过BL51连接定位后才能确定。为了能够在C51程序中直接对任意指定的存储器地址进行操作,可以采用扩展关键字“at”、指针、预定义以及连接定位控制命令。
中断号和中断源的对应关系
using m指明该中断服务程序所对应的工作寄存器组,取值范围:0~3。指定工作寄存器组的缺点是所有被中断调用的过程都必须使用同一个寄存器组,否则参数传递会发生错误。通常不设定using m,除非保证中断程序中未调用其他子程序。
使用C51编写中断服务程序,程序员无需关心ACC、B、DPH、DPL、PSW等寄存器的保护,C51编译器会根据上述寄存器的使用情况在目标代码中自动增加压栈和出栈。
XBYTE[0x8300]=0; /*向外部存储器(XDATA)地址0x8300写0
本人强烈建议用at,这样可能会更好些,还有一点就是不能乱用,因为有些存储器空间不能随便占用,C51编译器已经做其它的用了,而且有些空间单片机本身就做了很重要的作用,如果乱用,很容易出错。
#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 XWORD((unsigned int volatile *)0x20000L)
这些函数原型放在absacc.h文件中。
CBYTE以字节形式对CODE区寻址,DBYTE以字节形式对DATA区寻址,PBYTE以字节形式对PDATA区寻址,XBYTE以字节形式对XDATA区寻址,CWORD以字形式对CODE区寻址,DWORD以字形式对DATA区寻址,PWORD以字形式对PDATA区寻址,XWORD以字形式对XDATA区寻址。例如:
dp=0x61;
*dp=0x23;
idp=&ivar1;
*idp=0x16;
}
2. 使用C51运行库中预定义宏
C51编译器提供了一组宏定义用来对80C51系列单片机的CODE、DATA、PDATA和XDATA空间进行绝对地址访问。函数原型如下:
#define CWORD ((unsigned int volatile code *) 0)
#define DWORD ((unsigned int volatile data *) 0)
#define PWORD ((unsigned int volatile pdata *) 0)
(2).数据类型: 可以用int、long、float等基本类型,当然也可以用数组、结构等复杂数据类型类型,本人认为一般用unsigned int 就可以解决很多问题了。
(3).标识符: 就是要定义的变量名,编程者自己决定
(4).地址常数就是要直接操作的存储器的绝对地址,必须位于有效的存储器空间之内。
uchar idata ivar1;
uchar xdata *xdp;
char data *dp;
uchar idata *idp;
xdp=0x1000;
*xdp=0x5A;
在这些方法中,本人认为最简单而有效的方法是用“ _at_ ”关键字来对指定变量存储器空间绝对地址来指定。一般格式如下:
[存储器类型] 数据类型 标识符 _at_ 地址常数
其中:
(1).存储器类型: idata、data、xdata等C51能够识别的所有类型,最好不要省略。
/*------------------------------------------------
ABSACC.H
Direct access to 8051, extended 8051 and Philips 80C51MX memory areas.
Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
其中,存储器类型为idata、data、xdata等C51能识别的数据类型,如果省略该选项,则按编译模式SMALL、COMPAC或TLARGE规定的默认存储器类型确定变量的存储器空间;数据类型除了可用int、long、float等基本类型外,还可采用数组、结构等复杂数据类型;常数规定变量的绝对地址,必须位于有效的存储器空间之内;使用_at_定义的变量只能为全局变量。例如:
……
while(1);
}
需要注意的是,ui_var1在外部存储器区访问0x0004。通过使用#define预处理器命令,可采用其他符号定义绝对地址。
3. 使用C51扩展关键字 _at_
使用_at_对指定的存储器空间的绝对地址进行定位,一般格式如下:
[存储器类型] 数据类型 标识符 _at_ 常数
rval=XWORD [0x0002];指向外RAM的0004h地址
2. _at_关键字
直接在数据定义后加上_at_ const即可,但是注意:
(1)绝对变量不能被初使化;
(2)bit型函数及变量不能用_at_指定。
例如:
idata struct link list _at_ 0x40;指定list结构从40h开始。
#include
#include
#define uchar unsigned char
#define uint unsigned int
void main(void)
{
uint ui_var1;
uchar uc_var1;
ui_var1 = XWORD [0x0002];
uc_var1 = XBYTE [0x0002];
5.5.5 中断服务程序
80C51的中断系统十分重要,C51编译器允许在C语言源程序中声明中断和编写中断服务程序,从而减轻了采用汇编程序编写中断服务程序的繁琐程度。通过使用interrupt关键字来实现。定义中断服务程序的一般格式如下:
void 函数名( ) interrupt n [using m]
xdata char text[25b] _at_0xE000;指定text数组从0E000H开始
提示:如果外部绝对变量是I/O端口等可自行变化数据,需要使用volatile关键字进行描述,请参考absacc.h。
3. 连接定位控制
此法是利用连接控制指令code xdata pdata \data bdata对“段”地址进行,如要指定某具体变量地址,则很有局限性,不作详细讨论。
#define DBYTE ((unsigned char volatile data *) 0)
#define PBYTE ((unsigned char volatile pdata *) 0)
#define XBYTE ((unsigned char volatile xdata *) 0)
相关文档
最新文档