keilc51下如何讓編譯器優先使用片內

時間 2021-10-20 12:22:26

1樓:匿名使用者

c51記憶體結構深度剖析

在編寫應用程式時,定義乙個變數,乙個陣列,或是說乙個固定**,到底儲存在什麼地方;當定義變數大小超過mcu的記憶體範圍時怎麼辦;如何控制變數定義不超過儲存範圍;以及如何定義變數才能使得變數訪問速度最快,寫出的程式執行效率最高。以下將一一解答。

1 六類關鍵字(六類儲存型別)

data idata xdata pdata code bdata

code: code memory (程式儲存器也即唯讀儲存器)用來儲存常量或是程式。code memory 採用16位位址線編碼,可以是在片內,或是片外,大小被限制在64kb

作用:定義常量,如八段數碼表或是程式設計使用的常,在定義時加上code 或明確指明定義的常量儲存到code memory(唯讀)

使用方法:

char code table=;

此關鍵字的使用方法等同於const

data data memory (資料儲存區)只能用於宣告變數,不能用來宣告函式,該區域位於片內,採用8位位址線編碼,具有最快的儲存速度,但是數量被限制在128byte或更少。

使用方法:

unsigned char data fast_variable=0;

idata idata memory(資料儲存區)只能用於宣告變數,不能用來宣告函式. 該區域位於片內,採用8位位址線編碼,記憶體大小被限制在256byte或更少。該區域的低位址區與data memory位址一致;高位址區域是52系列在51系列基礎上擴充套件的並與特殊功能暫存器具有相同位址編碼的區域。

即:data memory是idata memory的乙個子集。

xdata xdata memory 只能用於宣告變數,不能用來宣告函式,該區域位於mcu

外部,採用16位位址線進行編碼,儲存大小被限制在64kb以內。

使用方法:

unsigned char xdata count=0;

pdata pdata memory 只能用於宣告變數,不能用來宣告函式,該區域位於mcu外部,採用8位位址線進行編碼。儲存大小限制在256byte. 是xdata memory的低256byte。

為其子集。

使用方法

unsigned char pdata count=0;

bdata bdata memory 只能用於宣告變數,不能用來宣告函式。該區域位於8051內部位資料位址。定義的量儲存在內部位位址空間,可用位指令直接讀寫。

使用方法:

unsigned char bdata varab=0

注:有些資料講,定義字元型變數時,在預設unsigned 時,字元型變數,預設為無符號,與標準c不同,但我在keil uvision3中測試的時候發現並非如此。在預設的情況下預設為有符號。

或許在以前的編譯器是預設為無符號。所以看到有的資料上面這樣講的時候,要注意一下,不同的編譯器或許不同。所以我們在寫程式的時候,還是乖乖的把unsigned signed 加上,咱也別偷這個懶。

2函式的引數和區域性變數的儲存模式

c51 編譯器允許採用三種儲存器模式:small,compact 和large。乙個函式的儲存器模式確定了函式的引數的區域性變數在記憶體中的位址空間。

處於small模式下的函式引數和區域性變數位於8051微控制器內部ram中,處於compact和large模式下的函式引數和區域性變數則使用微控制器外部ram。在定義乙個函式時可以明確指定該函式的儲存器模式。方法是在形參表列的後面加上一儲存模式。

示例如下:

#pragma large //此預編譯必須放在所有頭文前面

int func0(char x,y) small;

char func1(int x) large;

int func2(char x);

注:上面例子在第一行用了乙個預編譯命令#pragma 它的意思是告訴c51編譯器在對程式進行編譯時,按該預編譯命令後面給出的編譯控制指令large進行編譯,即本例程式編譯時的預設儲存模式為large.隨後定義了三個函式,第乙個定義為small儲存模式,第二個函式定義為large第三個函式未指定,在用c51進行編譯時,只有最後乙個函式按large儲存器模式處理,其它則分別按它們各自指定的儲存器模式處理。

本例說明,c51編譯器允許採用所謂的儲存器混合模式,即允許在乙個程式中將一些函式使用一種儲存模式,而其它一些則按另一種儲存器模式,採用儲存器混合模式程式設計,可以充分利用8051系列微控制器中有限的儲存器空間,同時還可以加快程式的執行速度。

3絕對位址訪問 absacc.h(相當重要)

#define cbyte ((unsigned char volatile code *) 0)

#define dbyte ((unsigned char volatile data *) 0)

#define pbyte ((unsigned char volatile pdata *) 0)

#define xbyte ((unsigned char volatile xdata *) 0)

功能:cbyte 定址 code區

dbyte 定址 data區

pbyte 定址 xdata(低256)區

xbyte 定址 xdata區

例: 如下指令在對外部儲存器區域訪問位址0x1000

xvar=xbyte[0x1000];

xbyte[0x1000]=20;

#define cword ((unsigned int volatile code *) 0)

#define dword ((unsigned int volatile data *) 0)

#define pword ((unsigned int volatile pdata *) 0)

#define xword ((unsigned int volatile xdata *) 0)

功能:與前面的乙個巨集相似,只是它們指定的資料型別為unsigned int .。

通過靈活運用不同的資料型別,所有的8051位址空間都是可以進行訪問。

如dword[0x0004]=0x12f8;

即內部資料儲存器中(0x08)=0x12; (0x09)=0xf8

注:用以上八個函式,可以完成對微控制器內部任意rom和ram進行訪問,非常方便。還有一種方法,那就是用指鍾,後面會對c51的指標有詳細的介紹。

4暫存器變數(register)

為了提高程式的執行效率,c語言允許將一些頻率最高的那些變數,定義為能夠直接使用硬體暫存器的所謂的暫存器變數。定義乙個變數時,在變數型別名前冠以「register」 即將該變數定義成為了暫存器變數。暫存器變數可以認為是一自動變數的一種。

有效作用範圍也自動變數相同。由於計算機暫存器中暫存器是有限的。不能將所有變數都定義成為暫存器變數,通常在程式中定義暫存器變數時,只是給編譯器乙個建議,該變數是否真正成為暫存器變數,要由編譯器根據實際情況來確定。

另一方面,c51編譯器能夠識別程式中使用頻率最高的變數,在可能的情況下,即使程式中並未將該變數定義為暫存器變數,編譯器也會自動將其作為暫存器變數處理。被定義的變數是否真正能成為暫存器變數,最終是由編譯器決定的。

5記憶體訪問雜談

1指鍾指鍾本身是乙個變數,其中存放的內容是變數的位址,也即特定的資料。8051的位址是16位的,所以指標變數本身占用兩個儲存單元。指標的說明與變數的說明類似,僅在指標名前加上「*」即可。

如 int *int_point; 宣告乙個整型指標

char *char_point; 宣告乙個字元型指標

利用指標可以間接訪問變數。實現這一點要用到兩個特殊運算子

& 取變數位址

* 取指標指向單元的資料

示例一:

int a,b;

int *int_point; //定義乙個指向整型變數的指標

a=15;

指向 a

*int_point=5; //給int_point指向的變數a 賦值5 等同於a=5;

示例二:

char i,table[6],*char_point;

char_point=table;

for(i=0;i<6;i++)

注:指標可以進行運算,它可以與整數進行加減運算(移動指標)。但要注意,移動指標後,其位址的增減量是隨指標型別而異的,如,浮點指標進行自增後,其內部將在原有的基礎上加4,而字元指標當進生自增的時候,其內容將加1。

原因是浮點數,佔4個記憶體單元,而字元佔乙個位元組。

巨集晶科技最新一代stc12c5a360s2系列,每乙個微控制器出廠時都有全球唯一身份證號碼(id號),使用者可以在微控制器上電後讀取內部ram單元f1h~f7h的數值,來獲取此微控制器的唯一身份證號碼。使用mov @ri 指令來讀取。下面介紹c51 獲取方法:

char id[7]=;

char i;

char idata *point;

for(i=0;i<7;i++)

(此處只是對指標做乙個小的介紹,達到訪問內部任何空間的方式,後述有對指標使用的詳細介紹)

2對sfr,ram ,rom的直接訪問

c51提供了一組可以直接對其操作的擴充套件函式

若源程式中,用#include包含標頭檔案,io51.h 後,就可以在擴充套件函式中使用特殊功能暫存器的位址名,以增強程式的可讀性:

注 此方法對sfr,ram,rom的直接訪問不建議使用.因為,淡io51.h這個標頭檔案在keil中無法開啟,可用指標,或是採用absacc.h標頭檔案,

Keil C51微控制器符串陣列問題高手來啊

看到了你前面的提問,用sprintf函式是可以的,但是資料部分要轉為整形,sprintf沒有uchar型別。uchar xdata cc commend 400 uchar xdata cc string1 57 uchar xdata cc string2 19 uchar xdata cc st...

菜鳥求教!如何讓電腦連線5 1音箱

告時芳劇亥 我的電腦連線功放是這樣的 整合音效卡輸出六個聲道那種,裡面只有三個聲道有用,乙個主聲道,乙個環繞,乙個中置加低音,買三根一轉二的音訊線,同軸的那種,輸入乙個同軸頭,輸出二個蓮花頭,我用這種方式連線的,dts與杜比都有效。 嬴淑敏湯環 我昨天就是這樣設定的,我在音訊屬性裡的高階選項裡把桌面...

如何讓5 1聲道完美實現

片源肯定是帶5.1的,功放支援dts,後面有12個輸入介面,10個輸出介面。但是電視輸出的是2聲道的,功放接上去根本不響,只有接有源2.0音箱可以響。筆記本沒有單獨的音訊輸出,只有一個耳機和話筒的標記,不知道能否支援光纖輸出。是不是要另外加音效卡啊。 首先得有dts,srs或sts音源,可以本本直接...