51微控制器c語言 幾個陣列定義的區別

時間 2021-12-21 11:17:17

1樓:

const 表示本陣列不可修改 陣列為常量陣列

code 表示本陣列生成後是在rom區中 同樣不可修改

idata 表示陣列生成後在在0x00~0xff的256個ram中,使用指標定址

具體的參考下面

data,bdata,idata,pdata,xdata,code儲存型別與儲存區

bit是在內部資料儲存空間中 20h .. 2fh 區域中一個位的地址,或者 8051 位可定址 sfr 的一個位地址。

code是在 0000h .. 0ffffh 之間的一個**地址。

data是在 0 到 127 之間的一個資料儲存器地址,或者在 128 .. 255 範圍內的一個特殊功能暫存器(sfr)地址。

idata是 0 to 255 範圍內的一個 idata 儲存器地址。

xdata 是 0 to 65535 範圍內的一個 xdata 儲存器地址。

指標型別和儲存區的關係詳解

一、儲存型別與儲存區關係

data ---> 可定址片內ram

bdata ---> 可位定址的片內ram

idata ---> 可定址片內ram,允許訪問全部內部ram

pdata ---> 分頁定址片外ram (movx @r0) (256 byte/頁)

xdata ---> 可定址片外ram (64k 地址範圍)

code ---> 程式儲存區 (64k 地址範圍),對應movc @dptr

二、指標型別和儲存區的關係

對變數進行宣告時可以指定變數的儲存型別如:

uchar data x和data uchar x相等價都是在內ram區分配一個位元組的變數。

同樣對於指標變數的宣告,因涉及到指標變數本身的儲存位置和指標所指向的儲存區位置不同而進行相應的儲存區型別關鍵字的

使用如:

uchar xdata * data pstr

是指在內ram區分配一個指標變數("*"號後的data關鍵字的作用),而且這個指標本身指向xdata區("*"前xdata關鍵字的作用),

可能初學c51時有點不好懂也不好記。沒關係,我們馬上就可以看到對應「*」前後不同的關鍵字的使用在編譯時出現什麼情況。

......

uchar xdata tmp[10]; //在外ram區開闢10個位元組的記憶體空間,地址是外ram的0x0000-0x0009

......

第1種情況:

uchar data * data pstr;

pstr=tmp;

首先要提醒大家這樣的**是有bug的, 他不能通過這種方式正確的訪問到tmp空間。 為什麼?我們把編譯後看到下面的彙編

**:mov 0x08,#tmp(0x00) ;0x08是指標pstr的儲存地址

看到了嗎!本來訪問外ram需要2 byte來定址64k空間,但因為使用data關鍵字(在"*"號前的那個),所以按keilc編譯環境來說

就把他編譯成指向內ram的指標變數了,這也是初學c51的朋友們不理解各個儲存型別的關鍵字定義而造成的bug。特別是當工程中的

預設的儲存區類為large時,又把tmp[10] 宣告為uchar tmp[10] 時,這樣的bug是很隱祕的不容易被發現。

第2種情況:

uchar xdata * data pstr;

pstr = tmp;

這種情況是沒問題的,這樣的使用方法是指在內ram分配一個指標變數("*"號後的data關鍵字的作用),而且這個指標本身指向

xdata區("*"前xdata關鍵字的作用)。編譯後的彙編**如下。

mov 0x08,#tmp(0x00) ;0x08和0x09是在內ram區分配的pstr指標變數地址空間

mov 0x09,#tmp(0x00)

這種情況應該是在這裡所有介紹各種情況中效率最高的訪問外ram的方法了,請大家記住他。

第3種情況:

uchar xdata * xdata pstr;

pstr=tmp;

這中情況也是對的,但效率不如第2種情況。編譯後的彙編**如下。

mov dptr, #0x000a ;0x000a,0x000b是在外ram區分配的pstr指標變數地址空間

mov a, #tmp(0x00)

mov @dptr, a

inc dptr

mov a, #tmp(0x00)

movx @dptr, a

這種方式一般用在內ram資源相對緊張而且對效率要求不高的專案中。

第4種情況:

uchar data * xdata pstr;

pstr=tmp;

如果詳細看了第1種情況的讀者發現這種寫法和第1種很相似,是的,同第1 種情況一樣這樣也是有bug的,但是這次是把pstr分

配到了外ram區了。編譯後的彙編**如下。

mov dptr, #0x000a ;0x000a是在外ram區分配的pstr指標變數的地址空間

mov a, #tmp(0x00)

movx @dptr, a

第5種情況:

uchar * data pstr;

pstr=tmp;

大家注意到"*"前的關鍵字宣告沒有了,是的這樣會發生什麼事呢?下面這麼寫呢!對了用齊豫的一首老歌名來說就是 「請跟我

來」,請跟我來看看編譯後的彙編**,有人問這不是在講c51嗎?為什麼還要給我們看彙編**。c51要想用好就要儘可能提升c51

編譯後的效率,看看編譯後的彙編會幫助大家儘快成為生產高效c51**的高手的。還是看**吧!

mov 0x08, #0x01 ;0x08-0x0a是在內ram區分配的pstr指標變數的地址空間

mov 0x09, #tmp(0x00)

mov 0x0a, #tmp(0x00)

注意:這是新介紹給大家的,大家會疑問為什麼在前面的幾種情況的pstr指標變數都用2 byte空間而到這裡就用3 byte空間了

呢?這是keilc的一個系統內部處理,在keilc中一個指標變數最多佔用 3 byte空間,對於沒有宣告指標指向儲存空間型別的指標,

系統編譯**時都強制載入一個位元組的指標型別分辯值。具體的對應關係可以參考keilc的help中c51 user's guide。

第6種情況:

uchar * pstr;

pstr=tmp;

這是最直接最簡單的指標變數宣告,但他的效率也最低。還是那句話,大家一起說好嗎!編譯後的彙編**如下。

mov dptr, #0x000a ;0x000a-0x000c是在外ram區分配的pstr指標變數地址空間

mov a, #0x01

mov @dptr, a

inc dptr

mov dptr, #0x000a

mov a, #tmp(0x00)

mov @dptr, a

inc dptr

mov a, #tmp(0x00)

movx @dptr, a

這種情況很類似第5種和第3種情況的組合,既把pstr分配在外ram空間了又增加了指標型別的分辨值。

2樓:傑青的日子

const:通常型別是指使用型別修飾符const說明的型別,常型別的變數或物件的值是不能被更新的。(當然,我們可以偷樑換柱進行更新)可以定義const常量,具有不可變性。

code 表示本陣列生成後是在rom區中 同樣不可修改。

idata 表示陣列生成後在在0x00~0xff的256個ram中,使用指標定址。

data,bdata,idata,pdata,xdata,code儲存型別與儲存區

bit是在內部資料儲存空間中 20h .. 2fh 區域中一個位的地址,或者 8051 位可定址 sfr 的一個位地址。

code是在 0000h .. 0ffffh 之間的一個**地址。

data是在 0 到 127 之間的一個資料儲存器地址,或者在 128 .. 255 範圍內的一個特殊功能暫存器(sfr)地址。

idata是 0 to 255 範圍內的一個 idata 儲存器地址。

xdata 是 0 to 65535 範圍內的一個 xdata 儲存器地址。

3樓:

推崇一樓的答案,詳細!

微控制器c語言陣列最多能定義多少個元素?

4樓:投機士

原則上,c語言中陣列所包含的元素個數理論上多少都行,如果要開一個很大的陣列,比如int arrayint[10000][10000];在main()中宣告該陣列就會使應用程式退出,但是如果你把該陣列的宣告放在所有函式體之外,讓它變成一個全域性變數,就沒有任何限制了,你想開多大的陣列都可以。

但在微控制器c語言程式中,實際上還是有限制的,原因在於微控制器的儲存空間是有限的,陣列最多能有幾個元素取決於微控制器型號。

你定義了一個全域性的陣列,unsigned char型的陣列,最多只能有93個元素,說明你還有其他變數佔用儲存空間。如果需要一個512個元素的陣列,用的微控制器是stc15f2k60s2,可在定義陣列時進行xdata宣告,將陣列儲存於外部ram當中。

5樓:匿名使用者

看你用的微控制器有多少儲存空間(ram、rom)和資料的型別(字元型還是整型還是長整型等等)。

6樓:

和微控制器字長沒有關係。

51是8位,可以定義65535長的陣列。對微控制器來說還是儲存空間限制,編譯器一般都能滿足大陣列的定義。

51可以定義65535個位元組長的xdata陣列,可定義65531的code陣列,當然會有一個警告,因為定義了,卻沒有使用該陣列,我主程式裡只有while(1);,還要自己修改彙編startup.a51,不如陣列定義不了這麼長,那裡佔用rom。

7樓:

同微控制器的字長有關係,

8位————256

16位————65536

51微控制器的c語言與傳統的c語言有什麼區別

8樓:匿名使用者

區別還是有的,51微控制器的c語言面向的是微控制器,所以硬體方面的函式和定義更多,很多相同名稱的函式其實意思是不完全一樣的。比如printf函式,傳統的c語言是格式化輸出到顯示器顯示,而微控制器則是通過串列埠將資料格式化傳送出去。

微控制器C語言程式設計,51微控制器C語言程式設計

使用兩個定時器或一個定時器中使用兩個計數都能滿足你的要求。建議使用一個定時器和一個計數器即可,如計數器為i,則if i 測溫定時 0 溫度測量 if i 步進電機定時 0 步進電機控制 注 此時要求兩個控制模組的定時步長是一致,比如都是1ms 設定一個比較小的定時間隔,例如1ms,用靜態變數累加,比...

C語言51微控制器中斷巢狀問題

對於普通51而言,不會存在中斷巢狀的情況,只有如stc系列的51,可以設定4個級別的中斷優先順序才有巢狀情況的發生。雖然外部中斷0 定時器0,外部中斷啊1.表明了其優先順序的高低,只是同時申請中斷時高階的先響應而已,不會打斷低優先順序的中斷。 必須返回低階中斷,你可以設定一個標誌位,在退出高階中斷時...

微控制器C語言程式設計,微控制器C語言程式設計題

按你的程式的結構,不做大的變動,又能理解的方法 四個程式合併成一個,當然就只能有一個主程式了,一個while 1 了,凡是while 1 以上的程式只保留一個就行了。四個程式的while 1 以下的都合併寫在一個while 1 下面,分為四段。有四個按鍵,判斷按鍵被按下的程式會寫吧?那判斷每個按鍵的...