新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 51單片機(jī)同時外擴(kuò)RAM,ROM的具體實現(xiàn)及Keil的具體設(shè)置

51單片機(jī)同時外擴(kuò)RAM,ROM的具體實現(xiàn)及Keil的具體設(shè)置

作者: 時間:2016-11-19 來源:網(wǎng)絡(luò) 收藏
51MCU內(nèi)部有RAM,ROM,不同于8031。盡管如今的增強(qiáng)行51MCU的內(nèi)部RAM,ROM可能已經(jīng)很大的空間。但就技術(shù)而言,擴(kuò)展RAM,ROM還是需要學(xué)會的。
對于不同的設(shè)計方案需求,擴(kuò)展可能基于以下任何一種設(shè)計:
A,只擴(kuò)展RAM
B,只擴(kuò)展ROM
C,擴(kuò)展ROM,RAM
總線擴(kuò)展時,P2口是否可用做普通IO口
這種擴(kuò)展是基于總線擴(kuò)展的,所以,P0P2口就已經(jīng)不可以再做它用了(有網(wǎng)友提供信息,總線擴(kuò)展P2還可以做普通IO口用,有兩種可能:1,P2口復(fù)用,如同P1利用373鎖存器。2,在總線擴(kuò)展時,只用到了低地址總線,P2口未用到。就作為普通IO口應(yīng)用。由于技術(shù)還不到位,不做評論。)
*擴(kuò)展RAM程序
擴(kuò)展RAM,在程序中定義的xdata類型 XBYTE類型等地址范圍在外部RAM的變量,對其讀寫的過程。用C51語言編寫程序,且使用總線擴(kuò)展的RAM,則時序電路不用考慮,WR RD等信號由編譯器/硬件自動完成。
編譯器設(shè)置*
內(nèi)部RAM:0x00~~0xFF
外部RAM:0x0000~~0xFFFF
RAM的地址雖重復(fù),但是兩個RAM是沒有關(guān)系的,所以不會造成干擾
使用了外部RAM,就在工程選項---off-chip xdata memory中設(shè)置 start:0x0000 size:0xFFFF(根據(jù)具體的RAM大小設(shè)置size)。
*擴(kuò)展RAM時的變量定位及連續(xù)讀取問題*
ROM,RAM的擴(kuò)展時,需要用到變量的絕對地址定位,函數(shù)定位等。
變量的絕對地址定位,是由于在程序中可能需要即時讀取某個變量,但變量的類型可能是XDATA,存儲在外部RAM中。這里有兩個方法:
1,用 _at_ 定位 關(guān)鍵字定位
unsigned char xdata xxx _at_ 0x1100 //定義變量XXX數(shù)據(jù)類型xdata,位置0x1100
[memory_space]tepe variable_name _at_ constant;
*絕對地址的變量不可以被初始化;函數(shù)或BIT類型的變量是不可以被定義為絕對地址;
2,用 XBYTE 定位 宏定義 絕對地址訪問
#define CBYTE((unsigned char volatile code*)0)
#define DBYTE((unsigned char volatile idata*)0)
#define PBYTE((unsigned char volatile pdata*)0)
#define XBYTE((unsigned char volatile xdata*)0)
////////////////////////////////////////////////////////////////////////////
#define CWORD((unsigned int volatile code*)0)
#define DWORD((unsigned int volatile idata*)0)
#define PWORD((unsigned int volatile pdata*)0)
#define XWORD((unsigned int volatile xdata*)0)
以上是宏定義的原型函數(shù),定義在 #include 頭文件中
#defme xxx XBYTE[0x8000] //變量類型為unsigned char 類型的數(shù)據(jù)xxx,位置xdata 0x8000
yyy=XBYTE[0x8000]; //變量類型為unsigned char 類型的數(shù)據(jù)yyy,位置xdata 0x8000
(在這里,有網(wǎng)友提到,當(dāng)編譯器優(yōu)化時,用絕對地址定位的變量,可能導(dǎo)致變量在連續(xù)讀取時出
錯,采用解決方法:
a,將編譯器優(yōu)化調(diào)整為0,即不優(yōu)化,程序不用修改,做以下操作
>>選擇project窗口的Target,然后打開"OptionsforTarget” 設(shè)置對話框,選擇“C5l”選項卡,
將“Code Optimiztaion”中的“Level”選擇為“0:Costant folding”。再次編譯<<
b,修改變量定義,增加“volatile”關(guān)鍵字說明其特征:就是說明該變量具有‘揮發(fā)’性,每次的讀取都一
有意義的,這樣編譯器即使在優(yōu)化時,編譯后的代碼也不會省略掉重復(fù)讀取的過程。如:
unsigned char volatile xdata xxx_at_0x8000;
由上文XBYTE等的宏定義函數(shù)原型可以看出,該宏定義已經(jīng)說明了變量具有volatile特性,因此,
也可以直接用XBYTE定義所需要的變量
c,硬件解決辦法
以上解決方法為參考網(wǎng)絡(luò)文章)
*擴(kuò)展ROM時的函數(shù)定位函數(shù)一部分在內(nèi)部ROM,一部分在外部ROM中
函數(shù)定位,個人理解:當(dāng)一個完整功能的程序存儲在外部內(nèi)部ROM中時,即利用了內(nèi)部ROM,可能由于內(nèi)部ROM空間不夠,部分函數(shù)在外部中,這時,如果要執(zhí)行整個功能,就需要告訴編譯器,其他功能函數(shù)的地址(函數(shù)在外部ROM中的地址),此時就要用到函數(shù)定位功能。解決方法如下:
....待續(xù).....
51內(nèi)部ROM地址范圍0x0000~0x0FFF,所以外部ROM的地址為0x1000~~最大0xFFFF。
c51bbs有詳細(xì)介紹
編寫完整的程序(如果建立兩個工程,堆棧等可能分配位置不同,導(dǎo)致地址重復(fù)或多個地址出錯),
編譯后查看.M51文件,找到需要定位的函數(shù)名稱信息(如?PR?_BCD2HEX?TOOLS),在KEIL51工程選項---BL51 lacate中code項中加入:?PR?_BCD2HEX?TOOLS(0x1000)再次編譯工程,打開.M51文件會發(fā)現(xiàn)?PR?_BCD2HEX?TOOLS已經(jīng)定位在了0x1000位置了。
如果有多個程序需要定位,方法同上,找出函數(shù)的名稱信息,添加到BL51 locate的CODE項中,每個函數(shù)之間用逗號隔開。而且要注意,所要定位的多個函數(shù)根據(jù)定位設(shè)置之前的地址高低安排,仍舊是低地址函數(shù)在前,高地址函數(shù)在后。
程序分為兩部分存儲,需要做的設(shè)置等如下:
....待續(xù).....
完成函數(shù)定位設(shè)置后,由于函數(shù)是要燒錄在兩個ROM中,需要將HEX文件分割成兩個,內(nèi)部ROM空間范圍與外部ROM空間范圍是不一樣的,自然就應(yīng)該將內(nèi)部ROM的地址范圍的HEX代碼存儲為一個文件,將剩余部分的代碼存儲為另一個文件,就完成了分割。
例如HEX文件的0x0000~~0x0FFF地址劃分為一個文件,0x1000~~0xFFFF劃分為另一個文件。
這一點,如果所用的MCU的內(nèi)部ROM大小不一致,就需要根據(jù)具體的大小劃分分割HEX文件。
*編譯器設(shè)置
由于是內(nèi)部ROM和外部擴(kuò)展ROM同時使用,在工程選項off-chip memory中需要設(shè)置外部ROM地址范圍,如eprom start:0x1000 size:0xFFFF(根據(jù)具體ROM大小設(shè)置size,同時use on-chip memory選項不選,電路中EA接高電平)
*擴(kuò)展ROM,所有程序都在外部ROM中
51內(nèi)部ROM不夠用,但外部擴(kuò)展的ROM應(yīng)該足夠了,所以,在擴(kuò)展了ROM之后,盡量避免編程麻煩,所有功能均放在外部ROM中,此時需要的設(shè)置操作等如下:
....待續(xù).....
由于程序代碼只用到了外部ROM,程序編譯等不需要特殊的設(shè)置,按正常編譯。然后將整個代碼燒錄到外部ROM就可以了。也就不存在HEX文件分割的問題了。
*編譯器設(shè)置
由于只用到了外部ROM,在工程選項off-chip memory中需要設(shè)置外部ROM地址范圍,如eprom start:0x0000 size:0xFFFF(根據(jù)具體ROM大小設(shè)置size,同時use on-chip memory選項不選,電路中EA接低電平),這里的設(shè)置不同與內(nèi)外部ROM都用的情況,沒有使用內(nèi)部ROM的情況下需要地址從0x0000開始,程序的開始地址中斷向量等都在這里(具體參考內(nèi)部ROM地址的使用)。EA接低電平表示程序是從外部ROM開始讀起的,即不用內(nèi)部ROM。
擴(kuò)展ROM,RAM時,總線地址如何安排*
在擴(kuò)展了ROM,RAM時,總線地址要如何安排,具體怎樣設(shè)置呢?操作如下:
......待續(xù).......
在程序設(shè)計時,要考慮硬件連接。例如,在外部ROM,RAM的地址設(shè)置時(keil工程選項中),假設(shè)P15初始化置1了或在程序中,P15為1時WR RD信號才時序正常(使用了74門電路),則keil工程選項中的地址設(shè)置就要考慮工作狀態(tài)P15是0或1的情況了。頁選信號就是從這里這樣而來的,P15頁選或地址線高字節(jié)頁選。
*硬件連接,需要考慮的問題
擴(kuò)展ROM,RAM時,硬件需要則樣連接?總線上的時續(xù),總線設(shè)備的速度匹配問題?
.......待續(xù)........
使用總線方式連接擴(kuò)展設(shè)備時,51總線有固定的時序,時序也就決定了速度。比如每個讀寫的過程,相應(yīng)的信號持續(xù)時間長短,擴(kuò)展設(shè)備能否在這個周期內(nèi)完成工作,是需要51的總線時序和擴(kuò)展設(shè)備的時序匹配才可以的。


評論


技術(shù)專區(qū)

關(guān)閉