51單片機的RAM區域劃分以及常遇到的問題

51單片機的RAM區域劃分以及常遇到的問題

前幾天群裡有一位同學使用AT89S51這個單片機編程,遇到了一個情況:keil軟件的options for Target的Target選項中,其中的Memory Model選項,同樣的程序,如果選擇Small模式進行編譯,把程序下載到單片機內,程序就工作正常;如果選擇Large模式進行編譯,下載到單片機內程序就工作不正常,這個就是新手偶爾遇到,但是很難分析出原因的內存使用溢出問題。


51單片機的問題,是歷史問題,比較複雜,那現在一般一些新型單片機這種問題就簡單一些,但是也得注意關於RAM的溢出問題。RAM是用來保存臨時數據的,一旦我們的使用量超過了RAM的大小或者區域,那就可能造成一些不可預知的錯誤問題。

51單片機的RAM分為片內和片外,標準的51內核是0x00~0x7F一共128B,而現在的大多數半導體廠商開發的51系列單片機都帶了擴展片內RAM,即片內RAM區域一般是從0x00到0xFF一共256B。隨著功能需求越來越多,程序量越來越大,那片內這256B也不夠用了,因此又擴展了片外RAM,片外RAM的預留比較大,最大可以從0x0000到0xFFFF一共64KB,當然了,每個具體型號有多大不一定,具體看通過芯片的手冊來了解。

而現在的51單片機的片外RAM, “片外”只是一個名詞而已,實際上很多也是直接做到了單片機內部,但是訪問地址,還是以外部的起始地址的方式。就是說,片內RAM的地址從0x00到0xFF,而片外是從0x0000到0xFFFF;其中最開始的256B是重複的地址,這部分通常情況下只要RAM夠用就可以不理會,軟件編譯器會自動給我們處理好。當選默認small模式,優先使用內部的前128B,而選Large模式,優先使用的是片外的64K。因此上面那個同學的問題就在這裡了,因為他用的是AT89S51單片機,而這個單片機是沒有片外RAM的,如果選擇了Large模式,那優先使用的是片外,因此編譯完成,下載到單片機裡,程序運行時用了這個單片機所沒有的區域,那肯定就不行了。


通常KEIL C51語言中的以下幾個關鍵字,代表了RAM不同區域的劃分:

data:片內RAM從0x00~0x7F

idata:片內RAM從0x00~0xFF

pdata:片外RAM從0x00~0xFF

xdata:片外RAM從0x0000~0xFFFF

其中,data是idata的一部分,pdata是xdata的一部分。這個問題我們可以不關心,只和彙編編程有關。

那如果選擇了small模式,我們定義一個變量a:unsigned char a = 0;他是默認保存在data區域,這個時候data是可以省略,但是我們想定義到xdata區域,就必須前邊加xdata關鍵字:unsigned char xdata a = 0;

如果選擇large模式,unsigned char a = 0;是定義在片外xdata區域,如果要定義在片內就必須加data關鍵字。

但是在RAM夠用的情況下,我們優先使用data的,其次使用idata關鍵字,再次使用pdata關鍵字,最後使用xdata。這個和底層訪問指令有關係,用前邊的讀寫速度要快一些,比如pdata訪問是單字節地址,而xdata是雙字節地址,訪問速度就慢了。


這裡講解C51的RAM,但是通過51的RAM同學們也得理解其他類型單片機的RAM使用問題,如果你不瞭解,一旦遇到RAM溢出,查找問題不好查。


分享到:


相關文章: