Keil C51中变量和函数的绝对地址定位问题:
1.  变量绝对地址定位
1)    在定义变量时使用 _at_ 关键字加上地址就可.
<
unsigned char idata myvar _at_ 0x40;
把变量 myvar 定义在 idata 的 0x40 处, 在 M51 文件中可以到这麽一行
IDATA  0040H    0001H    ABSOLUTE
表示有变量在 idata 的 0x0040 处绝对地址定位.
2)    使用 KeilC 编译器定义绝对地址的变量
只有全局变量可以绝对定位,局部变量无法实现绝对定位。
方法1:使用_at_关键字。声明一个全局变量unsigned char data MyBuf1[8] _at_ 0x20;
方法2:使用BL51 Locate选项。比如将main.c中定义的所有data型的全局变量定位到数据区D:0x28开始的空间,则从菜单中
选择Project->Options for Target 'Target1',在弹出的对话框中选择BL51 Locate 页,在下面的data栏中写上?DT?MAIN(0x28)即可。
如果是idata,则使用?ID?MAIN(0x28),如果是xdata,则使用?XD?MAIN(0x28),如果是pdata,则使用?PD?MAIN(0x28)
如果是Code,刚在code栏中写?CO?MAIN(0x28)
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单片机编程的时,常常需要进行绝对地址进行访问.特别是对硬件操作,如DA AD 采样 ,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对“段”地址进行,如要指定某具体变量地址,则很有局限性,不作详细讨论。

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