日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]對(duì) 51 單片機(jī)內(nèi)存的認(rèn)識(shí),很多人有誤解,最常見的是以下兩種① 超過變量128后必須使用compact模式編譯 實(shí)際的情況是只要內(nèi)存占用量不超過 256.0 就可以用 small 模式編譯② 128以上的某些地址為特殊寄存器使用,不能

對(duì) 51 單片機(jī)內(nèi)存的認(rèn)識(shí),很多人有誤解,最常見的是以下兩種

① 超過變量128后必須使用compact模式編譯
實(shí)際的情況是只要內(nèi)存占用量不超過 256.0 就可以用 small 模式編譯
② 128以上的某些地址為特殊寄存器使用,不能給程序用
與 PC 機(jī)不同,51 單片機(jī)不使用線性編址,特殊寄存器與 RAM 使用重復(fù)的重復(fù)的地址。但訪問時(shí)采用不同的指令,所以并不會(huì)占用 RAM 空間。

由于內(nèi)存比較小,一般要進(jìn)行內(nèi)存優(yōu)化,盡量提高內(nèi)存的使用效率。

以 Keil C 編譯器為例,small 模式下未指存儲(chǔ)類型的變量默認(rèn)為data型,即直接尋址,只能訪問低 128 個(gè)字節(jié),但這 128 個(gè)字節(jié)也不是全為我們的程序所用,寄存器 R0-R7必須映射到低RAM,要占去 8 個(gè)字節(jié),如果使用寄存組切換,占用的更多。

所以可以使用 data 區(qū)最大為 120 字節(jié),超出 120 個(gè)字節(jié)則必須用 idata 顯式的指定為間接尋址,另外堆棧至少要占用一個(gè)字節(jié),所以極限情況下可以定義的變量可占 247 個(gè)字節(jié)。當(dāng)然,實(shí)際應(yīng)用中堆棧為一個(gè)字節(jié)肯定是不夠用的,但如果嵌套調(diào)用層數(shù)不深,有十幾個(gè)字節(jié)也夠有了。


為了驗(yàn)上面的觀點(diǎn),寫了個(gè)例子

#define LEN 120
data UCHAR tt1[LEN];
idata UCHAR tt2[127];

void main()
{
UCHAR i,j;

for(i = 0; i < LEN; ++i )
{
j = i;
tt1[j] = 0x55;
}
}

可以計(jì)算 R0-7(8) + tt1(120) + tt2(127) + SP(1) 總共 256 個(gè)字節(jié)

keil 編譯的結(jié)果如下:
Program Size: data=256.0 xdata=0 code=30
creating hex file from ".DebugTest"...
".DebugTest" - 0 Error(s), 0 Warning(s).
(測試環(huán)境為 XP + Keil C 7.5)

這段代碼已經(jīng)達(dá)到了內(nèi)存分配的極限,再定義任何全局變量或?qū)?shù)組加大,編譯都會(huì)報(bào)錯(cuò) 107

這里要引出一個(gè)問題:為什么變量 i、j 不計(jì)算在內(nèi)?
這是因?yàn)?i、j 是局部變量,編譯器會(huì)試著將其優(yōu)化到寄存器 Rx 或棧。問題也就在這了,如果局部變量過多或定義了局部數(shù)組,編譯器無法將其優(yōu)化,就必須使用 RAM 空間,雖然全局變量的分配經(jīng)過精心計(jì)算沒有超出使用范圍,仍會(huì)產(chǎn)生內(nèi)存溢出的錯(cuò)誤!

而編譯器是否能成功的優(yōu)化變量是根據(jù)代碼來的
上面的代碼中,循環(huán)是臃腫的,變量 j 完全不必要,那么將代碼改成

UCHAR i;
UCHAR j;

for(i = 0; i < LEN; ++i )
{
tt1[i] = 0x55;
}

再編譯看看,出錯(cuò)了吧!
因?yàn)榫幾g器不知道該如何使用 j,所以沒能優(yōu)化,j 須占 RAM 空間,RAM 就溢出了。
(智能一點(diǎn)的編譯器會(huì)自動(dòng)將這個(gè)無用的變量去掉,但這個(gè)不在討論之列了)

另外,對(duì) idata 的定義的變量最好放在 data 變量之后

對(duì)于這一種定義


uchar c1;
idata uchar c2;
uchar c3;
變量 c2 肯定會(huì)以間接尋址,但它有可能落在 data 區(qū)域,就浪費(fèi)了一個(gè)可直接尋址的空間


變量優(yōu)化一般要注意幾點(diǎn):

①讓盡可能多的變量使用直接尋址,提高速度
假如有兩個(gè)單字節(jié)的變量,一個(gè)長119的字符型數(shù)組
因?yàn)榭傞L超過 120 字節(jié),不可能都定義在 data 區(qū)
按這條原則,定義的方式如下:


data UCHAR tab[119];
data UCAHR c1;
idata UCHaR c2;
但也不是絕的,如果 c1, c2 需要以極高的頻率訪問,而 tab 訪問不那么頻繁
則應(yīng)該讓訪問量大的變量使用直接尋址:

data UCAHR c1;
data UCHaR c2;
idata UCHAR tab[119];
這個(gè)是要根據(jù)具體項(xiàng)目需求來確定的

②提高內(nèi)存的重復(fù)利用率
就是盡可能的利用局部變量,局部變量還有個(gè)好處是訪問速度比較快
由前面的例子可以看出,局部變量 i, j 是沒有單獨(dú)占用內(nèi)存的
子程序中使用內(nèi)存數(shù)目不大的變量盡量定義為局部變量

③對(duì)于指針數(shù)組的定義,盡可能指明存儲(chǔ)類型
盡量使用無符號(hào)類型變量

一般指針需要一個(gè)字節(jié)額外的字節(jié)指明存儲(chǔ)類型
8051 系列本身不支持符號(hào)數(shù),需要外加庫來處理符號(hào)數(shù),一是大大降低程序運(yùn)行效率,二是需要額外的內(nèi)存


④避免出現(xiàn)內(nèi)存空洞

可以通過查看編譯器輸出符號(hào)表文件(.M51)查看
對(duì)前面的代碼,M51文件中關(guān)于內(nèi)存一節(jié)如下:


* * * * * * * D A T A M E M O R Y * * * * * * *
REG 0000H 0008H ABSOLUTE "REG BANK 0"
DATA 0008H 0078H UNIT ?DT?TEST
IDATA 0080H 007FH UNIT ?ID?TEST
IDATA 00FFH 0001H UNIT ?STACK


第一行顯示寄存器組0從地址0000H開始,占用0008H個(gè)字節(jié)
第二行顯示DATA區(qū)變量從0008H開始,占用0078H個(gè)字節(jié)
第三行顯示IDATA區(qū)變量從0080H開始,占用007F個(gè)字節(jié)
第四行顯示堆棧從00FFH開始,占0001H個(gè)字節(jié)

由于前面代碼中變量定義比較簡單,且連續(xù)用完了所有空間,所以這里顯示比較簡單
變量定義較多時(shí),這里會(huì)有很多行

如果全局變量與局部變量分配不合理,就有可能出現(xiàn)類似下面的行

0010H 0012H *** GAP ***
該行表示從0010H開始連續(xù)0012H個(gè)字節(jié)未充分利用或根本未用到
出現(xiàn)這種情況最常見的原因是局變量太多、多個(gè)子程序中的局部變量數(shù)目差異太大、使用了寄存器切換但未充分利用


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

在嵌入式系統(tǒng)的開發(fā)中,內(nèi)存資源的有限性常常成為設(shè)計(jì)者和開發(fā)者面臨的主要挑戰(zhàn)。特別是在那些對(duì)成本、功耗和尺寸有著嚴(yán)格要求的應(yīng)用中,如何在有限的內(nèi)存空間內(nèi)實(shí)現(xiàn)高效、可靠的代碼運(yùn)行,成為了嵌入式系統(tǒng)開發(fā)中的核心問題。本文將深入...

關(guān)鍵字: 嵌入式系統(tǒng) 內(nèi)存優(yōu)化

單片機(jī)內(nèi)部有很多的特殊功能寄存器,每個(gè)寄存器在單片機(jī)內(nèi)部都分配有唯一的地址,一般我們會(huì)根據(jù)寄存器功能的不同給寄存器賦予各自的名稱,當(dāng)我們需要在程序中操作這些特殊功能寄存器時(shí),必須要在程序的最前面將這些名稱加以聲明,聲明的...

關(guān)鍵字: C51 數(shù)據(jù)類型 擴(kuò)充定義

數(shù)據(jù)元(Data Element),也稱為數(shù)據(jù)元素,是用一組屬性描述其定義、標(biāo)識(shí)、表示和允許值的數(shù)據(jù)單元,在一定語境下,通常用于構(gòu)建一個(gè)語義正確、獨(dú)立且無歧義的特定概念語義的信息單元。數(shù)據(jù)元可以理解為數(shù)據(jù)的基本單元,將若...

關(guān)鍵字: C51 數(shù)據(jù)類型

▼點(diǎn)擊下方名片,關(guān)注公眾號(hào)▼歡迎關(guān)注【玩轉(zhuǎn)單片機(jī)與嵌入式】公眾號(hào),回復(fù)關(guān)鍵字獲取更多免費(fèi)資料。回復(fù)【加群】,限時(shí)免費(fèi)進(jìn)入知識(shí)共享群;回復(fù)【3D封裝庫】,常用元器件的3D封裝庫;回復(fù)【電容】,獲取電容、元器件選型相關(guān)的內(nèi)容...

關(guān)鍵字: C51 MDK RealView

遠(yuǎn)程智能雙引擎,共推全球生命科學(xué)創(chuàng)新 上海2021年11月18日 /美通社/ -- 由法國達(dá)索系統(tǒng)全資子公司Medidata舉辦的第十屆Med...

關(guān)鍵字: idata

在Keil C51軟件中51單片機(jī)的中斷服務(wù)和外設(shè)驅(qū)動(dòng)程序的開發(fā)

關(guān)鍵字: keil5 編譯 C51

Intel公司1980年推出了MCS-51系列單片機(jī):集成 8位CPU、4K字節(jié)ROM、128字節(jié)RAM、4個(gè)8位并口、1個(gè)全雙工串行口、2個(gè)16位定時(shí)/計(jì)數(shù)器。尋址范圍64K,并有控制功能較強(qiáng)的布爾處理器。 80C5...

關(guān)鍵字: C51 KEIL 編程

c上標(biāo)3下標(biāo)5怎么算用計(jì)算機(jī),c上標(biāo)3下標(biāo)5怎么算

關(guān)鍵字: C51 KEIL

▼點(diǎn)擊下方名片,關(guān)注公眾號(hào)▼大家好,很高興和各位一起分享我的第16篇原創(chuàng)文章,喜歡和支持我的工程師,一定記得給我點(diǎn)贊、收藏、分享。加微信[xyzn3333]與作者溝通交流,免費(fèi)獲取更多單片機(jī)與嵌入式的海量電子資料。很多初...

關(guān)鍵字: 51單片機(jī) C51

常看見初學(xué)者要求使用_at_,這是一種謬誤,把C當(dāng)作ASM看待了。在C中變量的定位是編譯器的事情,初學(xué)者只要定義變量和變量的作 用域,編譯器就把一個(gè)固定地址給這個(gè)變量。

關(guān)鍵字: C51 單片機(jī) 誤區(qū) 注意事項(xiàng)
關(guān)閉