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
中填入:
再次編譯即可。
相應地,如為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、堆疊定位:
在STARTUP.A51檔案中定義了堆疊區?STACK,其起始地址同樣可以在BL51 Locate頁中設定,在Stack欄寫上?STACK(0x80)
還可以通過彙編實現
// 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;
BL51 locate 選項卡中
code range 和 xdata range如果不填寫,編譯預設將程式中相應程式碼和變數從空間前面取起
網上看到有人提到在keil中使用_at_進行絕對地址定位問題,我簡單介紹一下它的用法。
使用_at_關鍵字對儲存器進行絕對地址定位程式如下
#i nclude<reg51.h>
char xdata LED_Data[50] _at_ 0x8000;
main()
{
LED_Data[0] = 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之絕對地址定位
微控制器空間分配看*.M51檔案,ARM,DSP空間分配看*.map檔案 1、函式定位: 假如要把C原始檔 tools.c 中的函式 int BIN2HEX(int xx) { ... } 放在CODE MEMORY的0x1000處,先編譯該工程,然後開啟該工程的
SourceInsight之絕對地址和相對地址
在SourceInsight中,新建的工程基本都是基於絕對地址的,因此如果要把程式碼移到另一臺電腦上時,便需要刪除先前的檔案並重新新增。另一個解決這個問題的方法便是將程式碼的檔案路徑設為相對地址,修改為相對路徑的步驟如下: 首先是按照正常操作建立絕對地址的Sourc
IAR STM32 函式和變數的絕對地址定位
昨天我突然冒出個想法,能否利用函式和變數的絕對定位,實現程式的模組化更新。 也就是說,如果我要改變某個函式,只需要更新flash裡面一個區域性,也許只需要更新幾百個位元組,而無須重新下載整個上百K的程式。 經過查詢資料和反覆實驗,終於實現了,現總結如下: 1) 把函
CSS之絕對定位
用戶 note alt src 基礎 讓我 blue 分享 出現 w3school定義: 絕對定位的元素的位置相對於最近的已定位祖先元素,如果元素沒有已定位的祖先元素,那麽它的位置相對於最初的包含塊。 對於定位的主要問題是要記住每種定位的意義。所以,現在讓我們復習一下學
【轉載】CSS之絕對定位及相對定位
通過 原本 second span sof 動手 lan 根據 為什麽 我們先來看看CSS3 Api中對position屬性的相關定義: static:無特殊定位,對象遵循正常文檔流。top,right,bottom,left等屬性不會被應用。 relative:對象遵
HTML之絕對定位Absolute
HTML之絕對定位 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8">
Keil C51對C語言的關鍵詞擴充套件之八: far
far的出現,是Keil 編譯器為了支援新出現的8051家族增強型MCU,這些增強型MCU可能擁有大於64KB的儲存器。使用far可訪問擴充套件的RAM,使用const far可訪問擴充套件的ROM。 NXP 51MX架構51微控制器提供通過通用指標訪問多達8MB的code
51微控制器中將變數、陣列、函式設定在固定位置,定位到絕對地址
一、不帶初值的變數或陣列 直接使用_at_ 關鍵字加上地址就行。 如: unsigned char idata myvar _at_ 0x40; unsigned char code myvar[10] _at_ 0x40; _at_ 關鍵字
Keil C51對C語言的關鍵詞擴充套件之十三: sfr
sfr用來定義特殊功能暫存器。用法如下: sfr name = address; name 為暫存器名字 address 為暫存器的地址 示例: sfr P0 = 0x80; /* P0口,地址為0x80 */ sfr P1 = 0x90;/* P1口,地址為0x90
Keil C51對C語言的關鍵詞擴充套件之二: alien
alien關鍵詞主要是為了C51編譯器與PL/M-51編譯器相容。 在C51編譯器中呼叫PL/M-51函式,須使用alien宣告該函式,如下: extern alien char plm_func (int, char); char c_func (void) {
Keil C51對C語言的關鍵詞擴充套件之五: code
code 指定儲存位置位於程式儲存器。程式儲存器只讀,因此code型別的變數,是無法再次賦值的。 unsigned char code ary[ ] = :"Read only"; /* 陣列ary位於程式儲存器 */ ary[0]='a'; /* 錯誤,不可修改*/
Keil C51對C語言的關鍵詞擴充套件之十: pdata
外部ram通過一個地址指標暫存器來間接訪問,讀寫效率要低於內部ram。 外部ram容量最大可位64KB。 Keil C51提供兩種外部資料儲存方式,pdata和xdata。 1)xdata儲存型別,指示變數可儲存在外部ram 64KB地址範圍內任意位置。large記憶體模型
CSS設計美麗之絕對定位(absolute)的使用(小作品)
關於HTML與CSS的小作品之一: 前端已經學習過絕對定位的概念了: 絕對定位:脫離文件流,以 離自己最近定位的祖先元素(position) 為參照物,如果沒有定位的祖先元素,則追溯到以body為參照物,通過四個偏移屬性進行偏移,不會影響文件中的元素,其margin不會與
Keil C51對C語言的關鍵詞擴充套件之十一: xdata
xdata宣告的變數位於外部ram 64KB地址範圍內某一位置。 程式示例: unsigned int xdata m=0; /* 宣告一個全域性變數,可位於外部ram 64KB地址範圍內任意位置,由
elf檔案中程式碼段有絕對地址但重定位表中無.text.rel
#include int main() { printf("hello\n"); return 0; }
Keil C51對C語言的關鍵詞擴充套件之六: compact
函式的引數和區域性變數儲存在記憶體模型指定的預設區域內。 我們可以通過small,compact 或large 指定一個函式使用何種記憶體模型。 #pragma small /* 預設記憶體模型為small*/ extern int calc (char
OpenStack(ice house)雲主機獲取不到DHCP地址之故障分析定位與處理辦法
公司生產機房最近淘汰下來一批裝置,不算太舊,普遍CPU兩顆兩核,少數四顆四核,但其中已經有若干臺主機安裝不了CentOS7的系統了。因為主機型號太舊,CentOS7已經不提供磁碟驅動的支援了。所以只好將就著裝成了CentOS6.7。為了更好得發揮餘熱,著手部署了一套Open
散列技術之鏈地址法(基於無序鏈表)
stc 分享 item size obj 單鏈表 結果 clu arc 源碼例如以下: #include <stdlib.h> #include <stdio.h> #define hash(v,M) (v % M) typedef c
iOS開發之地圖與定位
control 移動 idt line tor mkmapview 什麽 .cn 構建 不管是QQ還是微信的移動client都少不了定位功能,之前在微信demo中沒有加入定位功能,今天就寫個定位的小demo來了解一下定位和地圖的東西。地圖和定位看上去是挺高大
Appium python自動化測試系列之元素的定位(六)
keditor logs ren 匹配 4.4 contex 應用 需要 運用 ?6.1 常用定位方法講解 對象定位是自動化測試中很關鍵的一步,也可以說是最關鍵的一步,畢竟你對象都沒定位那麽你想操作也不行。所以本章節的知識我希望大家多動手去操作,不要僅僅只是書本上的知識,畢