




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、關(guān)于單片機時鐘周期機器周期(12個晶振時鐘為一個機器周期的原因):傳統(tǒng)的51執(zhí)行指令時,需要取指、譯碼、執(zhí)行等,而這其中每步還可以精細劃分,這些步驟依靠時鐘執(zhí)行。標準51這個過程設(shè)計為12步,因此12個時鐘是一個完整的指令周期新的51系統(tǒng)很多都對這個過程進行了優(yōu)化,因而不需要這么多步,也就不是12分頻了根據(jù)單片機實現(xiàn)精準延時:以10ms延時子程序(12MHz)為例來分析一下(其它的類似)void delay10ms(void)unsigned char i,j,k;for(i=5;i0;i-)for(j=4;j0;j-)for(k=248;k0;k-);這個程序有三層循環(huán),循環(huán)的總次數(shù)為Num
2、=5*4*248=4960每次循環(huán)都有一次條件判斷(如“k0”)和一次只減(如“k-”),即每次循環(huán)消耗兩個機器周期那么花費的總的機器周期即為Sum=Num*2=9920對于51單片機12M晶振的話一個周期是1us,那么延時時間t=Sum*1us=9 920 us 10ms這段程序有可能是精確延時到10ms,這是因為調(diào)用這個函數(shù)及執(zhí)行完這個函數(shù)分別要壓棧和出棧,另外i,j,k也有一個賦初值的過程.所以各種因素疊加到一起延時就是10ms了關(guān)于keil error107內(nèi)存溢出問題ERROR L107: ADDRESS SPACE OVERFLOW問題原因分析及解決用KEIL選用small模式編譯
3、一個程式時老時出錯,信息如下。* ERROR L107: ADDRESS SPACE OVERFLOWProgram Size: data=217.6 xdata=0 code=5314Target not created芯片我選的是AT89C52,RAM有256呀,怎么會OVERFLOW呢?但是如果編譯模式選用Compact或large時就一切正常。Program Size: data=110.6 xdata=111 code=5914test - 0 Error(s), 22 Warning(s).請大俠們指教!-排開Keil編譯器有問題,可以肯定是你的內(nèi)存空間溢出了Keil 中關(guān)于 10
4、7 錯誤的描述是這樣的:=Error L107 (ADDRESS SPACE OVERFLOW)Summary * Error L107ADDRESS SPACE OVERFLOWSPACE: space-nameSEGMENT: segment-nameDescription The specified segment cannot be located at the specified address space. The segment is ignored. =如果你仍要堅持自己的觀點,只能去問 keil 公司的前面有些兄弟的說法有二點是不確切的:就是超過變量128后必須使用compa
5、ct模式編譯實際的情況是只要編譯指示data=xxx 不超過 256.0 就可以用 small 編譯128以上的某些地址為特殊寄存器使用,不能給程序用特殊寄存器雖然使用重復(fù)的地址,但是用不同的指令訪問,并不會占用RAM空間但 small 模式下未指存儲類型的變量默認為data型,即直接尋址,只能訪問低 128 個字節(jié),但這 128 個字節(jié)也不是全為你程序所有,寄存器 R0-R7必須映射到低RAM,要占去 8 個字節(jié),如果使用寄存組切換,占用的更多。所以你可以使用 data 區(qū)最大為 120 字節(jié),超出 120 個字節(jié)則必須用 idata 顯示的指定為間接尋址,另外堆棧至少要占用一個字節(jié),所以你
6、最多能使用 127 上字節(jié)(如果)就是說極限情況下你可以定義的變量可占 247 個字節(jié)當(dāng)然,實際應(yīng)用中堆棧為一個字節(jié)肯定是不夠用的,但如果嵌套調(diào)用層數(shù)不深,有十幾個字節(jié)也夠有了,所以你的 217.6 個字節(jié)的占用量應(yīng)該是可以滿足的為了驗上面的觀點,寫了個例子#define LEN 120data UCHAR tt1LEN;idata UCHAR tt2127;void main()UCHAR i,j;for(i = 0; i LEN; +i )j = i;tt1j = 0x55;可以計算 R0-7(8) + tt1(120) + tt2(127) + SP(1) 總共 256 個字節(jié)keil
7、編譯的結(jié)果如下:Program Size: data=256.0 xdata=0 code=30creating hex file from .DebugTest.DebugTest - 0 Error(s), 0 Warning(s).(我的測試環(huán)境為 XP + Keil C 7.5)這段程序已經(jīng)達到了內(nèi)存分配的極限,再定義任何全局變量或?qū)?shù)組加大,編譯都會報錯 107,也就是跟你碰到的一樣的錯誤信息這里就要引出一個問題:為什么變量 i、j 不計算在內(nèi)?這是因為 i、j 是局部變量,編譯器會試著將其優(yōu)化到寄存器 Rx 或棧。問題也就在這了,如果局部變量過多中定義了局部數(shù)組,編譯器無法將其優(yōu)化
8、,就必須使用 RAM 空間,雖然全局變量的分配經(jīng)過精心計算沒有超出使用范圍,仍會產(chǎn)生內(nèi)存溢出的錯誤!而編譯器是否能成功的優(yōu)化變量是根據(jù)你的代碼來的上面的代碼中,循環(huán)是臃腫的,變量 j 是完全不必要,那么將代碼改成UCHAR i;UCHAR j;for(i = 0; i 可尋址片內(nèi)rambdata - 可位尋址的片內(nèi)ramidata - 可尋址片內(nèi)ram,允許訪問全部內(nèi)部rampdata - 分頁尋址片外ram (MOVX R0) (256 BYTE/頁)xdata - 可尋址片外ram (64k 地址范圍FFFFH)code - 程序存儲區(qū) (64k 地址范圍),對應(yīng)MOVC DPTR二、指針
9、類型和存儲區(qū)的關(guān)系對變量進行聲明時可以指定變量的存儲類型如:uchar data x和data uchar x相等價都是在內(nèi)ram區(qū)分配一個字節(jié)的變量。同樣對于指針變量的聲明,因涉及到指針變量本身的存儲位置和指針所指向的存儲區(qū)位置不同而進行相應(yīng)的存儲區(qū)類型關(guān)鍵字的使用如:uchar xdata * data pstr是指在內(nèi)ram區(qū)分配一個指針變量(*號后的data關(guān)鍵字的作用),而且這個指針本身指向xdata區(qū)(*前xdata關(guān)鍵字的作用),可能初學(xué)C51時有點不好懂也不好記。沒關(guān)系,我們馬上就可以看到對應(yīng)“*”前后不同的關(guān)鍵字的使用在編譯時出現(xiàn)什么情況。uchar xdata tmp10;
10、 /在外ram區(qū)開辟10個字節(jié)的內(nèi)存空間,地址是外ram的0x00000x0009第1種情況:uchar data * data pstr;pstr=tmp;首先要提醒大家這樣的代碼是有bug的, 他不能通過這種方式正確的訪問到tmp空間。 為什么?我們把編譯后看到下面的匯編代碼:MOV 0x08,#tmp(0x00) ;0x08是指針pstr的存儲地址看到了嗎!本來訪問外ram需要2 byte來尋址64k空間,但因為使用data關(guān)鍵字(在*號前的那個),所以按KeilC編譯環(huán)境來說就把他編譯成指向內(nèi)ram的指針變量了,這也是初學(xué)C51的朋友們不理解各個存儲類型的關(guān)鍵字定義而造成的bug。特別
11、是當(dāng)工程中的默認的存儲區(qū)類為large時,又把tmp10 聲明為uchar tmp10 時,這樣的bug是很隱秘的不容易被發(fā)現(xiàn)。第2種情況:uchar xdata * data pstr;pstr = tmp;這種情況是沒問題的,這樣的使用方法是指在內(nèi)ram分配一個指針變量(*號后的data關(guān)鍵字的作用),而且這個指針本身指向xdata區(qū)(*前xdata關(guān)鍵字的作用)。編譯后的匯編代碼如下。MOV 0x08,#tmp(0x00) ;0x08和0x09是在內(nèi)ram區(qū)分配的pstr指針變量地址空間MOV 0x09,#tmp(0x00)這種情況應(yīng)該是在這里所有介紹各種情況中效率最高的訪問外ram的方
12、法了,請大家記住他。第3種情況:uchar xdata * xdata pstr;pstr=tmp;這中情況也是對的,但效率不如第2種情況。編譯后的匯編代碼如下。MOV DPTR, #0x000A ;0x000A,0x000B是在外ram區(qū)分配的pstr指針變量地址空間MOV A, #tmp(0x00)MOV DPTR, AINC DPTRMOV A, #tmp(0x00)MOVX DPTR, A這種方式一般用在內(nèi)ram資源相對緊張而且對效率要求不高的項目中。第4種情況:uchar data * xdata pstr;pstr=tmp;如果詳細看了第1種情況的讀者發(fā)現(xiàn)這種寫法和第1種很相似,是
13、的,同第1 種情況一樣這樣也是有bug的,但是這次是把pstr分配到了外ram區(qū)了。編譯后的匯編代碼如下。MOV DPTR, #0x000A ;0x000A是在外ram區(qū)分配的pstr指針變量的地址空間MOV A, #tmp(0x00)MOVX DPTR, A第5種情況:uchar * data pstr;pstr=tmp;大家注意到*前的關(guān)鍵字聲明沒有了,是的這樣會發(fā)生什么事呢?下面這么寫呢!對了用齊豫的一首老歌名來說就是 “請跟我來”,請跟我來看看編譯后的匯編代碼,有人問這不是在講C51嗎? 為什么還要給我們看匯編代碼。C51要想用好就要盡可能提升C51編譯后的效率,看看編譯后的匯編會幫助
14、大家盡快成為生產(chǎn)高效C51代碼的高手的。還是看代碼吧!MOV 0x08, #0X01 ;0x080x0A是在內(nèi)ram區(qū)分配的pstr指針變量的地址空間MOV 0x09, #tmp(0x00)MOV 0x0A, #tmp(0x00)注意:這是新介紹給大家的,大家會疑問為什么在前面的幾種情況的pstr指針變量都用2 byte空間而到這里就用3 byte空間了呢?這是KeilC的一個系統(tǒng)內(nèi)部處理,在KeilC中一個指針變量最多占用 3 byte空間,對于沒有聲明指針指向存儲空間類型的指針,系統(tǒng)編譯代碼時都強制加載一個字節(jié)的指針類型分辯值。具體的對應(yīng)關(guān)系可以參考KeilC的help中C51 Users Guide。第6種情況:uchar * pstr;pstr=tmp;這是最直接最簡單的指針變量聲明,但他的效率也最低。還是那句話,大家一起說好嗎!編
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年人格心理學(xué)課程考試題及答案
- 2025年圖書情報學(xué)相關(guān)考試試卷及答案
- 2025年電氣工程師資格考試題及答案
- 2025年建筑工程管理試題及答案
- 三人合伙協(xié)議合同范本
- 房屋分租合同協(xié)議書范本
- 2025屆高考語文復(fù)習(xí):散文主旨意蘊+課件
- Web前端開發(fā)技術(shù)項目教程(HTML5 CSS3 JavaScript)(微課版) 課件 項目6 非遺項目申報指南頁面
- 骨科宣教護理
- 酒店模塊化精裝修及智能化系統(tǒng)安裝合同
- 2025閩教版英語三年級下冊單詞表
- 預(yù)防性健康檢管理制度管理辦法
- 英漢語法對比研究
- 材料的斷裂(1)
- CAAP2008X功能概述PPT課件
- 柴油發(fā)電機組檢查驗收表_word文檔免費
- 被子植物門分科檢索表
- XX水庫工程度汛方案專家組評審意見
- 全國職業(yè)院校技能大賽高職組汽車檢測與維修賽項競賽試題答案集
- 百勝餐飲HIC高效能的輔導(dǎo)
- 皇家寵物食品有限公司的營銷策略分
評論
0/150
提交評論