1.变量绝对地址定位
1)在定义变量时使用 _at_ 关键字加上地址就可.
e.g.
unsigned char idata myvar _at_ 0x40;
把变量 myvar 定义在 idata 的 0x40 处, 在 M51 文件中可以找到这麽一行
IDATA 0040H 0001H ABSOLUTE
表示有变量在 idata 的 0x0040 处绝对地址定位.
2) 使用 KeilC 编译器定义绝对地址的变量, 方法待查.
2. 函数绝对地址定位
1) 在程序中编写一函数 myTest
void myTest(void)
{
// Add your code here
}
2)使用KeilC 编译器定位绝对地址的函数, 打开Project -> Options for Target菜单,选中 BL51 Locate 选项卡, 在 Code: 中输入:
?PR?myTest?MAIN(0x4000)
把函数 myTest 定位到程序区的 0x4000 处,
再次编译就可以了.
3) 一次定位多个函数的方法
同样地, 在程序中再编写另外一个函数 myTest1
void myTest1(void)
{
// Add your code here
}
在 Options for Target 菜单的 BL51 Locate 选项卡的 Code: 中输入:
?PR?myTest1?MAIN(0x3900), ?PR?myTest?MAIN(0x4000)
把函数 myTest1 定位在程序区的 0x3900 处, 把函数 myTest 定义在程序区的 0x4000 处,重新编译就可以了.在 M51 文件中可以找到下面的内容:
>> 3.obj TO Reader RAMSIZE (256) CODE (?PR?MYTEST1?MAIN (0X3900), ?PR?MYTEST?MAIN (0X4000))
3665H 029BH *** GAP ***
CODE 3900H 0014H UNIT ?PR?MYTEST1?MAIN
3914H 06ECH *** GAP ***
CODE 4000H 0014H UNIT ?PR?MYTEST?MAIN
4) 函数的调用:
程序中直接调用函数的方式就不说明了, 这里重点讲使用函数指针调用绝对地址处的函数的方法.
(1) 定义调用的函数原形
typedef void (*CALL_MYTEST)(void);
这是一个回调函数的原形, 参数为空.
(2) 定义相应的函数指针变量
CALL_MYTEST myTestCall = NULL;
(3) 函数指针变量赋值, 指向我们定位的绝对地址的函数
myTestCall = 0x3900;
指向函数 myTest1
(4) 函数指针调用
if (myTestCall != NULL)
{
myTestCall();//调用函数指针处的函数myTest1,置PC指针为0x3900
}
检查编译生成的 bin 文件, 到 0x3900 处可以看到 myTest1 的内容, 在 0x4000 处可以看到 myTest 的内容,
(5)其它说明:
如果在0x3000到 0x3900 的程序空间没有内容时, 把 myTestCall 的地址指针指到 0x3800(在 0x3000 到 0x3900 之间) 时, 会从 0x3900 处开始执行.至於在 Load 中调用 AP 中的函数的方法与此类似, 但是相应的参数传递可能要另寻方法.
keil C51绝对地址访问
在利用keil进行8051单片机编程的时,常常需要进行绝对地址进行访问.特别是对硬件操作,如DAAD采样,LCD 液晶操作,打印操作.等等.
C51提供了三种访问绝对地址的方法:
1. 绝对宏:
在程序中,用“#include<absacc.h>”即可使用其中定义的宏来访问绝对地址,包括:
CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD
具体使用可看一看absacc.h便知
例如:
rval=CBYTE[0x0002];指向程序存贮器的0002h地址
rval=XWORD [0x0002];指向外RAM的0004h地址
2. _at_关键字
直接在数据定义后加上_at_ const即可,但是注意:
(1)绝对变量不能被初使化;
(2)bit型函数及变量不能用_at_指定。
例如:
idata struct link list _at_ 0x40;指定list结构从40h开始。
xdata char text[25b] _at_0xE000;指定text数组从0E000H开始
提示:如果外部绝对变量是I/O端口等可自行变化数据,需要使用volatile关键字进行描述,请参考absacc.h。
3. 连接定位控制
此法是利用连接控制指令code xdata pdata \data bdata对“段”地址进行,如要指定某具体变量地址,则很有局限性,不作详细讨论。