<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > C51,RAM 用C51操作片內(nèi)擴(kuò)展RAM

          C51,RAM 用C51操作片內(nèi)擴(kuò)展RAM

          作者: 時(shí)間:2016-11-25 來(lái)源:網(wǎng)絡(luò) 收藏
          很多工程師都遇到過(guò)的“怪現(xiàn)象”
          問(wèn)
          標(biāo)準(zhǔn)80C51、52內(nèi)核的單片機(jī)片內(nèi)最多只有256字節(jié)的RAM,少得可憐,很多情況下會(huì)出現(xiàn)不夠用的問(wèn)題。如果在片外擴(kuò)展RAM,則會(huì)增加成本,并可能減少多達(dá)18條I/O口線(xiàn)?,F(xiàn)在許多新型8051內(nèi)核的單片機(jī)為了解決上述問(wèn)題,會(huì)在片內(nèi)另外擴(kuò)展有一定容量的RAM,一般安排在XDATA地址空間。Philips半導(dǎo)體的P89C668更是在片內(nèi)擴(kuò)展有8KB的XRAM,與其它型號(hào)相比,堪稱(chēng)“海量”。為了保持與標(biāo)準(zhǔn)80C51的兼容性,一般這些擴(kuò)展的片內(nèi)RAM在復(fù)位時(shí)默認(rèn)是無(wú)效的,如果要使用,則需要先修改相關(guān)SFR寄存器里的使能位(但也有少數(shù)型號(hào)的規(guī)定與此恰恰相反,復(fù)位時(shí)默認(rèn)是有效的,如果片外已經(jīng)擴(kuò)展有XRAM,則地址重疊的部分會(huì)被自動(dòng)屏蔽掉)。
          如果使用匯編語(yǔ)言編程,在程序一開(kāi)始,可以立即使能片內(nèi)擴(kuò)展RAM,以后用MOVX指令就能方便地訪(fǎng)問(wèn)。如果用C51編程,許多用戶(hù)很自然地也在main()函數(shù)的一開(kāi)始就使能片內(nèi)擴(kuò)展RAM。然而在調(diào)試程序時(shí)總是出現(xiàn)意外情況,仔細(xì)排查后,“確認(rèn)”是片內(nèi)外部RAM有問(wèn)題,通常表現(xiàn)為數(shù)據(jù)沒(méi)有被初始化。部分客戶(hù)還會(huì)去找供應(yīng)商算帳,稱(chēng)芯片質(zhì)量存在嚴(yán)重問(wèn)題,等等??梢哉f(shuō),這是我們?cè)S多單片機(jī)工程師都曾經(jīng)遇到過(guò)的問(wèn)題。
          總之,你用C51編程并打算使用片內(nèi)擴(kuò)展的RAM,那么就很容易出現(xiàn)上述怪現(xiàn)象。是芯片有問(wèn)題嗎?不是!同樣功能的程序如果換作匯編來(lái)寫(xiě),就跑通了,這就證明芯片還是好的——找供應(yīng)商算帳無(wú)理!是C51編譯器有問(wèn)題嗎?更不是!C51編譯器是經(jīng)過(guò)多年千錘百煉才發(fā)展到今天“完善”的程度,想找出并證實(shí)一個(gè)bug還真不容易。“是我的程序錯(cuò)了嗎?程序很小,僅10幾行,專(zhuān)門(mén)測(cè)試片內(nèi)擴(kuò)展RAM用的,已經(jīng)過(guò)反復(fù)核查,怎么會(huì)出錯(cuò)呢?”——很多工程師對(duì)我這樣講,但我還是要告訴他:確實(shí)是程序有問(wèn)題!
          我們先不提程序錯(cuò)在何處,因?yàn)椴糠止こ處熜宰犹保蚁冉o出解決方案,行不行,先試試看:請(qǐng)刪除main()函數(shù)里使能片內(nèi)擴(kuò)展RAM的語(yǔ)句;重新建立工程,選擇器件后,Keil C51會(huì)提示是否復(fù)制并添加startup code到工程里,此時(shí)一定要選擇“是”;將你的相關(guān)C源程序添加進(jìn)工程;打開(kāi)剛才添加的Startup.A51文件,找到標(biāo)號(hào)“STARTUP1:”,緊接其后添加使能片內(nèi)擴(kuò)展RAM的匯編指令;重新編譯工程并調(diào)試。OK,問(wèn)題解決了嗎?
          咦——這是為什么?原因是這樣的:如果你用到了片內(nèi)擴(kuò)展RAM,定義有xdata屬性的全局變量(或在main()函數(shù)的開(kāi)頭定義有),而且定義的同時(shí)賦有初值,那么變量的初始化操作實(shí)際上在進(jìn)入main()函數(shù)之前(或剛進(jìn)入main函數(shù)時(shí),不可控)就已經(jīng)完成了。因此在main()函數(shù)里,第一條可執(zhí)行語(yǔ)句就安排為使能片內(nèi)擴(kuò)展RAM的操作已是來(lái)不及!這就是C51編譯器的特性,同時(shí)也是其它C編譯器所共有的、ANSI C所要求的。文件Startup.A51是啟動(dòng)代碼部分,里面包含有初始化全局變量的操作。新建工程時(shí),如果不添加此文件,則在編譯時(shí)系統(tǒng)也會(huì)自動(dòng)插入安裝目錄中的那個(gè)Startup.A51文件。如果在main()函數(shù)里的開(kāi)頭定義有xdata屬性的變量并賦初值,則執(zhí)行時(shí)剛一進(jìn)入main()該變量就被初始化,然后才輪到正常的可執(zhí)行語(yǔ)句。現(xiàn)在知道在main()中添加使能片內(nèi)擴(kuò)展RAM的操作語(yǔ)句為什么不行了嗎?
          答 1:
          一句話(huà)概括:在使能片內(nèi)擴(kuò)展RAM之前對(duì)XRAM進(jìn)行的任何操作都無(wú)效因此,相關(guān)使能片內(nèi)擴(kuò)展RAM的指令必須位于全局變量初始化操作之前。
          關(guān)于STC單片機(jī)內(nèi)部擴(kuò)展ram的使用
          高128字節(jié)(地址:80H~FFH),只可間接尋址;
          STC89系列單片機(jī)另外增加了768字節(jié)的片內(nèi)擴(kuò)展RAM,以解決眾多技術(shù)人員在編程時(shí)的RAM資源嚴(yán)重缺乏的問(wèn)題。
          768字節(jié)的片內(nèi)擴(kuò)展RAM(地址:000H~2FFH)與外部擴(kuò)展RAM地址重疊,單片機(jī)可通過(guò)軟件設(shè)置AUXR.1,決定是否使用片內(nèi)擴(kuò)展RAM,以防止可
          能的與外部擴(kuò)展RAM的沖突,默認(rèn)為使用片內(nèi)擴(kuò)展RAM。
          片內(nèi)擴(kuò)展RAM的訪(fǎng)問(wèn)采用間接尋址,可通過(guò)
          ①、MOVX A,@DPTR 或 MOVX @DPTR ,A 指令訪(fǎng)問(wèn)片內(nèi)擴(kuò)展RAM(00H~2FFH,共768字節(jié));
          ②、MOVX A,@Ri 或 MOVX @Ri,A 指令訪(fǎng)問(wèn)片內(nèi)擴(kuò)展RAM(00H~FFH,共256字節(jié))。
          當(dāng)DPTR≥300H時(shí),系統(tǒng)訪(fǎng)問(wèn)外部擴(kuò)展RAM。
          注意:在使用第二種指令時(shí),特別要注意是使用MOV還是MOVX,MOV訪(fǎng)問(wèn)的是片內(nèi)RAM,MOVX訪(fǎng)問(wèn)的是片內(nèi)擴(kuò)展RAM,剛剛接觸此類(lèi)單片機(jī)的技
          術(shù)人員最容易在這里犯錯(cuò)誤。


          關(guān)鍵詞: C51RAM片內(nèi)擴(kuò)

          評(píng)論


          技術(shù)專(zhuān)區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();