keil51中如何用C语言定义寄存器的地址并给地址赋值

keil51中如何用C语言定义寄存器的地址并给地址赋值,第1张

KeilC51中定义寄存器变量的方法闷旁如下:

1、特殊功能寄存器的定义:

sfr和sfr16,比如:

sfr P1=0x90

sfr16 T2=0xcc

2、普通寄存器变量凳租定义:

使用DBYTE和XBYTE来实现,比如

unsigned char temp=XBYTE[0x1000]//这是访问外部地址的语句,也可以是外部IO口地址

unsigned char temp=DBYTE[0x40]//这是将内蚂粗橡部寄存器40H定义为变量temp

那要看你的Keil究竟是指51工具链还是ARM工具链卜兄核。

如果是ARM,需要尘隐修改分散型掘加载文件,在指定的位置新增Section,之后在你的程序中声明将函数放在该Section中。

如果是51,那么在选项卡的Linker页面,在连接参数行添加参数,指定你那个函数块的绝对地址就行。

强大的MDK几乎可以满足我们所需要的所有功能。一般在链接时各程序的地址是由链接器自动分配的。但在有些时候,比如做测镇圆试时,需要将某个指定的子程序入口地址固定在一个指定的地址。其实通过一些简单的配置就可达到这一目的。下面以C51版MDK为例说明其配置过程。

比如某例程中有UART_VINIT、IO_VINIT、MAIN_VINIT、MAIN、TIMER2等函数。其中TIMER2是我们需要固定其入口地址的函数。编译链接之后在工程目录下会生成M51文件(后缀为M51)。可以用记事御前塌本将其打开。打开悔晌后我们找到LINK MAP OF MODULE 项,在默认编译链接情况下其内容为:

LINK MAP OF MODULE: T2test2 (TIMER)

TYPEBASE LENGTHRELOCATION SEGMENT NAME

-----------------------------------------------------

* * * * * * * D A T A M E M O R Y * * * * * * *

REG 0000H 0008H ABSOLUTE "REG BANK 0"

DATA0008H 0001H UNIT ?DT?MAIN?TIMER

DATA0009H 0001H UNIT ?DT?GETCHAR

000AH 0016H *** GAP ***

BIT 0020H.0 0000H.1 UNIT ?BI?GETCHAR

0020H.1 0000H.7*** GAP ***

IDATA 0021H 0001H UNIT ?STACK

* * * * * * * C O D E M E M O R Y * * * * * * *

CODE0000H 0003H ABSOLUTE

0003H 0028H *** GAP ***

CODE002BH 0003H ABSOLUTE

002EH 07D2H *** GAP ***

CODE0800H 0062H UNIT ?PR?MAIN?TIMER

CODE0862H 0027H UNIT ?PR?PUTCHAR?PUTCHAR

CODE0889H 0026H UNIT ?C?LIB_CODE

CODE08AFH 001FH UNIT ?PR?UART_VINIT?STARTUP

CODE08CEH 001EH UNIT ?PR?MAIN_VINIT?STARTUP

CODE08ECH 0011H UNIT ?PR?GETCHAR?GETCHAR

CODE08FDH 000CH UNIT ?C_C51STARTUP

CODE0909H 000BH UNIT ?PR?TIMER2?TIMER

CODE0914H 000AH UNIT ?PR?_GETKEY?_GETKEY

CODE091EH 0004H UNIT ?PR?IO_VINIT?STARTUP

以上就是链接后各函数的入口地址信息。找到我们需要指定入口地址的项。这里假设我们需要指定TIMER2这个子函数。找到其对应项“?PR?TIMER2?TIMER”,其中间部分即为函数名,后部分为所在文件名。我们发现其入口地址为0909H,长度为000BH。找到这一项之后,复制其值。然后打开菜单Project,选择Options,再选择BL51 Locate项。在Code栏后面的输入框里粘下所复制的值,然后在后面加上小括号,括号内给出其入口地址的值。如 ?PR?TIMER2?TIMER(0x1000)。如图一所示:

图一

点击确定后,重新编译链接,再打开M51文件,发现LINK MAP OF MODULE项内容变为:

LINK MAP OF MODULE: T2test2 (TIMER)

TYPEBASE LENGTHRELOCATION SEGMENT NAME

-----------------------------------------------------

* * * * * * * D A T A M E M O R Y * * * * * * *

REG 0000H 0008H ABSOLUTE "REG BANK 0"

DATA0008H 0001H UNIT ?DT?MAIN?TIMER

DATA0009H 0001H UNIT ?DT?GETCHAR

000AH 0016H *** GAP ***

BIT 0020H.0 0000H.1 UNIT ?BI?GETCHAR

0020H.1 0000H.7*** GAP ***

IDATA 0021H 0001H UNIT ?STACK

* * * * * * * C O D E M E M O R Y * * * * * * *

CODE0000H 0003H ABSOLUTE

0003H 0028H *** GAP ***

CODE002BH 0003H ABSOLUTE

002EH 07D2H *** GAP ***

CODE0800H 0062H UNIT ?PR?MAIN?TIMER

CODE0862H 0027H UNIT ?PR?PUTCHAR?PUTCHAR

CODE0889H 0026H UNIT ?C?LIB_CODE

CODE08AFH 001FH UNIT ?PR?UART_VINIT?STARTUP

CODE08CEH 001EH UNIT ?PR?MAIN_VINIT?STARTUP

CODE08ECH 0011H UNIT ?PR?GETCHAR?GETCHAR

CODE08FDH 000CH UNIT ?C_C51STARTUP

CODE0909H 000AH UNIT ?PR?_GETKEY?_GETKEY

CODE0913H 0004H UNIT ?PR?IO_VINIT?STARTUP

0917H 06E9H *** GAP ***

CODE1000H 000BH UNIT ?PR?TIMER2?TIMER

在链接信息中发现TIMER2函数已经定位到地址1000H。当然在下载到目标板或者在模拟器中调试时,可以发现在地址1000H处是函数TIMER2的入口地址。至此,子函数定位完成。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12435468.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存