2012年7月12日 星期四

51單片機編程在不同內存空間(data xdata bdata)定義變量的註意事項


1、data區空間小,所以只有頻繁用到或對運算速度要求很高的變量才放到data區內,比如for循環中的計數值。
2、data區內最好放局部變量。
因為局部變量的空間是可以覆蓋的(某個函數的局部變量空間在退出該函數是就釋放,由別的函數的局部變量覆蓋),可以提高內存利用率。當然靜態局部變量除外,其內存使用方式與全局變量相同;
3、確保你的程序中沒有未調用的函數。
Keil C裏遇到未調用函數,編譯器就將其認為可能是中斷函數。函數裏用的局部變量的空間是不釋放,也就是同全局變量一樣處理。這一點Keil C做得很愚蠢,但也沒辦法。
4、程序中遇到的邏輯標誌變量可以定義到bdata中,可以大大降低內存占用空間。
51系列芯片中有16個字節位尋址區bdata,其中可以定義8*16=128個邏輯變量。定義方法是:bdatabit LedState;但位類型不能用在數組和結構體中。
5、其他不頻繁用到和對運算速度要求不高的變量都放到xdata區。
6、如果想節省data空間就必須用large模式,將未定義內存位置的變量全放到xdata區。當然最好對所有變量都要指定內存類型。
7、當使用到指針時,要指定指針指向的內存類型。
C51中未定義指向內存類型的通用指針占用3個字節;而指定指向data區的指針只占1個字節;指定指向xdata區的指針占2個字節。如指針p是指向data區,則應定義為:char data *p;。還可指定指針本身的存放內存類型,如:char data * xdata p;。其含義是指針p指向data區變量,而其本身存放在xdata區。
單片機初學者一般對c51語言裏的DATA,XDATA,BDATA,IDATA,CODE,不是很清楚,因為在微機的c語言裏根本沒有這些東西,一下子出來難以讓人接受,特別是沒有硬件基本的朋友們.這也是寫程序的時候經常犯錯誤的地方。請看下表 
普通51系列單片機存儲空間資源分配情況

空間名稱
地址範圍
說明
DATAD:00H~7FH片內RAM直接尋址區
BDATAD:20H~2FH片內RAM位尋址區
IDATAI:00H~FFH片內RAM間接尋址區
XDATAX:0000H~FFFFH64K片外RAM數據區
CODEC:0000H~FFFFH64K片內外ROM代碼
BANK0~BANK31B0:0000H~FFFFH
:
:
B31:0000H~FFFFH
分組代碼區,最大可擴展32X64KB ROM





下表是新型80C51單片機擴展空間的分配情況

空間名稱
地址範圍
說明
DATAD:00H~7FH片內RAM直接尋址區
BDATAD:20H~2FH片內RAM位尋址區
IDATAI:00H~FFH片內RAM間接尋址區
XDATAX:0000H~FFFFH64KB常規片外RAM數據區
HDATAX:0000H~FFFFFFH16MB擴展片外RAM數據區
CODEC:0000H~FFFFH64K常規片內外ROM代碼區
HCONST(ECODE)C:0000H~FFFFFFH16MB擴展片外ROM常數區(對Dallas390可用作代碼區)
BANK0~BANK31B0:0000H~FFFFH
:
:
B31:0000H~FFFFH
分組代碼區,最大可擴展32X64KB ROM


單片機關鍵字data,idata,xdata,pdata的區別data:
固定指前面0x00-0x7f的128個RAM,可以用acc直接讀寫的,速度最快,生成的代碼也最小。

idata:
固定指前面0x00-0xff的256個RAM,其中前128和data的128完全相同,只是因為訪問的方式不同。idata是用類似C中的指針方式訪問的。匯編中的語句為:mox ACC,@Rx.(不重要的補充:c中idata做指針式的訪問效果很好)

xdata:
外 部擴展RAM,一般指外部0x0000-0xffff空間,用DPTR訪問。 pdata:外部擴展RAM的低256個字節,地址出現在A0-A7的上時讀寫,用movx ACC,@Rx讀寫。這個比較特殊,而且C51好象有對此BUG, 建議少用。但也有他的優點,具體用法屬於中級問題,這裏不提。

startup.a51的作用
和 匯編一樣,在C中定義的那些變量和數組的初始化就在startup.a51中進行,如果你在定義全局變量時帶有數值,如unsigned char data xxx="100";,那startup.a51中就會有相關的賦值。如果沒有=100,startup.a51就會把他清0。(startup.a51 ==變量的初始化)。 這些初始化完畢後,還會設置SP指針。對非變量區域,如堆棧區,將不會有賦值或清零動作。
有人喜歡改 startup.a51,為了滿足自己一些想當然的愛好,這是不必要的,有可能錯誤的。比如掉電保護的時候想保存一些變量, 但改startup.a51來實現是很笨的方法,實際只要利用非變量區域的特性,定義一個指針變量指向堆棧低部:0xff處就可實現。, 為什麽還要去改? 可以這麽說:任何時候都可以不需要改startup.a51,如果你明白它的特性
我最近在玩和訊微博,很方便,很實用,你也來和我一起玩吧!
去看看我的微博吧!http://t.hexun.com.tw/16372590/default.html


沒有留言: