KEIL C51之绝对地址定位
单片机空间分配看*.M51文件,ARM,DSP空间分配看*.map文件
1、函数定位
假如要把C源文件 tools.c 中的函数
int BIN2HEX(int xx) { ... }
放在CODE MEMORY的0x1000处,先编译该工程,然后打开该工程的M51文件,在
* * * C O D E M E M O R Y * * *
行下找出要定位的函数的名称,应该形如:
CODE xxxxH xxxxH UNIT ?PR?_BCD2HEX?TOOLS
然后在:Project->Options for Target ...->BL51 Locate:Code中填写如下内容:?PR?_BCD2HEX?TOOLS(0x1000)
再次Build,在M51中会发现该函数已放在CODE MEMORY的0x1000处了。
2、赋初值的变量定位
要将某变量定位在一绝对位置且要赋初值,此时用 _at_ 不能完成,则如下操作:
在工程中建立一个新的文件,如InitVars.c,在其中对要处理的变量赋初值(假设是code变量):
char code myVer = {"COPYRIGHT 2001-11"};
然后将该文件加入工程,编译,打开M51文件,若定义的是code型,则在
* * * C O D E M E M O R Y * * *下可找到:
CODE xxxxH xxxxH UNIT ?CO?INITVARS
然后在:Project->Options for Target ...->BL51 Locate:Code中填入:?CO?INITVARS(0x200) 再次编译即可。
相应地,如为xdata变量,则InitVars.c中写:char xdata myVer = {"COPYRIGHT 2001-11"};
然后将该文件加入工程,编译,打开M51文件,在
* * * X D A T A M E M O R Y * * *下可找到:
XDATA xxxxH xxxxH UNIT ?XD?INITVARS
然后在:Project->Options for Target ...->BL51 Locate:Xdata中填入:?XD?INITVARS(0x200)再次编译即可。
相应地,若定义的是data/idata等变量,则相应处理即可。
3、若有多个变量或函数要进行绝对地址定位,则应按地址从低到高的顺序
使用KeilC51软件,可以很方便地将代码或者数据绝对定位到某个地址。
1、代码定位
方法1:使用伪指令CSEG。比如要将MyFunc1定位到代码区C:0x1000,则新建一个A51文件,添加以下内容:
PUBLIC MYFUNC1 CSEG AT 1000H MYFUNC1: ;其它代码 RET
在其它源文件中,就可以调用MyFunc()函数了。需要注意的是,编译器不检测传递参数的数目,仅检测函数是否有返回值。
方法2:使用BL51 Locate选项。比如在main.c中定义了一个MyFunc2函数,并且要将该函数定位到代码区C:0x2000,则从菜单中选择Project->Options for Target 'Target1',在弹出的对话框中选择BL51 Locate页,在下面的code栏中写上?PR?MYFUNC2?MAIN(0x2000)即可。如果想定位多个函数,也可以使用*通配符。
2、变量定位
只有全局变量可以绝对定位,局部变量无法实现绝对定位。
方法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)。
方法3:还可以通过汇编实现
// my.a51 public my_flash_var cseg at 0F100H my_flash_var: db 55h end
然后C声明
// flash.c extern unsigned char code my_flash_var;
3、堆栈定位
在STARTUP.A51文件中定义了堆栈区?STACK,其起始地址同样可以在BL51 Locate页中设置,在Stack栏写上?STACK(0x80)
BL51 locate 选项卡中code range 和 xdata range如果不填写,编译默认将程序中相应代码和变量从空间前面取起。
网上看到有人提到在keil中使用_at_进行绝对地址定位问题,我简单介绍一下它的用法。
使用_at_关键字对存储器进行绝对地址定位程序如下
#include<reg51.h> ] _at_ 0x8000; main() { LED_Data[] = 0x23; }
在keil中运行以上程序可以在存储器窗口中输入 x:0x8000,可以看到0x8000地址中的值为0x23。值得指出的几点是
1、在给变量LED_Data[50]定位绝对地址空间时,不能对其赋初值。
2、char xdata LED_Data[50] _at_ 0x8000;这条语句不能主函数中。有些网友提到在按着keil说明中用_at_进行绝对地址定位时,编译会出现错误274,就是将这条语句放在主函数中的原因。
3、keil中地址是自动分配的,所以除非特殊情况否则不提倡使用绝对地址定位。初学者因帖别注意。不要把c当作汇编使用。
对需要/RST复位后要保持变量不变,防止意外改变(比如升级到新程序,变量地址可能被编译器优化到其他地方),比较有用!!!!
KEIL C51之绝对地址定位的更多相关文章
- keil C51绝对地址访问
在利用keil进行8051单片机编程的时,常常需要进行绝对地址进行访问.特别是对硬件操作,如DA AD 采样 ,LCD 液晶操作,打印操作.等等.C51提供了三种访问绝对地址的方法: 1. 绝对宏 在 ...
- Keil C51中变量和函数的绝对地址定位问题
1.变量绝对地址定位 1) 在定义变量时使用 _at_ 关键字加上地址就可. unsigned char idata myvar _at_ 0x40; 把变量 myvar 定义在 idata 的 0 ...
- keil中使用_at_绝对地址定位
使用_at_关键字对存储器进行绝对地址定位程序如下: #include<reg51.h> ] _at_ 0x8000; main() { LED_Data[] = 0x23; } 在kei ...
- Keil C51怎样将子程序段定位在固定的地址位?
以下2问题均要用C51解决1.怎样将1个子程序段定位在1个固定的地址位置?例如将 INT BCD2HEX(INT XX)定位在1000H2.如何在EEPROM 中固定的位置存放1字符串?如在200H处 ...
- KEIL C51高级编程
第一节 绝对地址访问C51提供了三种访问绝对地址的方法: 1. 绝对宏:在程序中,用“#include”即可使用其中定义的宏来访问绝对地址,包括:CBYTE.XBYTE.PWORD.DBYTE.CWO ...
- Keil C51 知识点
第一节 Keil C51扩展关键字 深入理解并应用C51对标准ANSIC的扩展是学习C51的关键之一.因为大多数扩展功能都是直接针对8051系列CPU硬件的.大致有以下8类: 8051存储类型 ...
- Keil C51 详细设置
一.target名更改 打开Keil后,左侧Project Workspace中的target可改,方法:右击Target——Manage Compnents——双击待修改项即可,若要添加,使用对话框 ...
- keil C51 指针总结
变量就是一种在程序执行过程中其值能不断变化的量.要在程序中使用变量必须先用标识符作为变量名,并指出所用的数据类型和存储模式,这样编译系统才能为变量分配相应的存储空间.定义一个变量的格式如下: [存储种 ...
- keil c51笔记
第一章 Keil C51开发系统基本知识 第一节 系统概述 Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上.结构性.可读性. ...
随机推荐
- 怎样在loop中处理异常
怎样在loop中处理异常,而不跳出 出现符号“exception”在需要下下列之一时的解决办法; 如果sql中发生异常,我们可以用 exception when others then d ...
- 在安装软件CAJViewer时出现,“错误1327。无效驱动器:F:
解决的方法:DOS中输入例如以下命令: [plain] view plaincopy subst F: %TEMP% 回车退出就可以,必要时重新启动电脑. 软件成功安装之后能够执行下面命令,将该虚拟分 ...
- 常用的bat命令
获取输入法adb shell settings get secure default_input_method修改输入法adb shell settings put secure default_in ...
- [WebStrom] Change default cmd to Cygwin
GO to setting, search Terminal: Change shell path : C:\cygwin\bin\bash.exe --login -i (to the loc ...
- (转)cocos2dx 内存管理
原文地址:http://blog.csdn.net/ring0hx/article/details/7946397 cocos2dx的内存管理移植自Objective-C, 对于没有接触过OC的C++ ...
- CSS3 @font-face使用实例
Windows10操作系统使用实例: 1.准备好对应格式的字体库 2.方正字体使用实例 <!DOCTYPE html> <html> <head> <meta ...
- Lock锁_线程_线程域
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...
- 解决ASP.NET中ReportView与IE11的兼容性问题
前久发现以前用ReportView开发的一个软件的报表,在IE11上运行时出错,陆续查了好几天才解决了问题. 开发环境: VS2010,ReportView 10.0.402,RDLC报表模板 问题: ...
- 一个PHP开发者总结的九条建议
本文只是个人从实际开发经验中总结的一些东西,并不是什么名言警句,写出来有两个目的:一是时刻提醒自己要按照这些知识点来写自己代码,二是为了分享,说不定对你有用呢?万一,是吧... 1.首要意识:安全 大 ...
- Android开发手记(16) 数据存储一 SharedPreferences
Android为数据存储提供了五种方式: 1.SharedPreferences 2.文件存储 3.SQLite数据库 4.ContentProvider 5.网络存储 SharedPreferenc ...