新聞中心

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

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

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


評(píng)論


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

關(guān)閉