久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

keil優(yōu)化等級(jí)設(shè)置

作者:佚名   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年09月01日   【字體:
優(yōu)化級(jí)別說(shuō)明(僅供參考):
則其中的 Code Optimization    欄就是用來(lái)設(shè)置C51的優(yōu)化級(jí)別。共有9個(gè)優(yōu)化級(jí)別(書(shū)上這么寫(xiě)的),高優(yōu)化級(jí)別中包含了前面所有的優(yōu)化級(jí)別。現(xiàn)將各個(gè)級(jí)別說(shuō)明如下:
0級(jí)優(yōu)化:
1、 常數(shù)折疊:只要有可能,編譯器就執(zhí)行將表達(dá)式化為常數(shù)數(shù)字的計(jì)算,其中包括運(yùn)行地址的計(jì)算。
2、 簡(jiǎn)單訪問(wèn)優(yōu)化:對(duì)8051系統(tǒng)的內(nèi)部數(shù)據(jù)和位地址進(jìn)行訪問(wèn)優(yōu)化。
3、 跳轉(zhuǎn)優(yōu)化:編譯器總是將跳轉(zhuǎn)延至最終目標(biāo)上,因此跳轉(zhuǎn)到跳轉(zhuǎn)之間的命令被刪除。
1級(jí)優(yōu)化:
1、 死碼消除:無(wú)用的代碼段被消除。
2、 跳轉(zhuǎn)否決:根據(jù)一個(gè)測(cè)試回溯,條件跳轉(zhuǎn)被仔細(xì)檢查,以決定是否能夠簡(jiǎn)化或刪除。
2級(jí)優(yōu)化:
1、 數(shù)據(jù)覆蓋:適于靜態(tài)覆蓋的數(shù)據(jù)和位段被鑒別并標(biāo)記出來(lái)。連接定位器BL51通過(guò)對(duì)全局?jǐn)?shù)據(jù)流的分析,選擇可靜態(tài)覆蓋的段。
3級(jí)優(yōu)化:
1、“窺孔”優(yōu)化:將冗余的MOV命令去掉,包括不必要的從存儲(chǔ)器裝入對(duì)象及裝入常數(shù)的操作。另外如果能節(jié)省存儲(chǔ)空間或者程序執(zhí)行時(shí)間,復(fù)雜操作將由簡(jiǎn)單操作所代替。
4級(jí)優(yōu)化:
1、 寄存器變量:使自動(dòng)變量和函數(shù)參數(shù)盡可能位于工作寄存器中,只要有可能,將不為這些變量保留數(shù)據(jù)存儲(chǔ)器空間。
2、擴(kuò)展訪問(wèn)優(yōu)化:來(lái)自IDATA、XDATA、PDATA和CODE區(qū)域的變量直接包含在操作之中,因此大多數(shù)時(shí)候沒(méi)有必要將其裝入中間寄存器。
3、局部公共子式消除:如果表達(dá)式中有一個(gè)重復(fù)執(zhí)行的計(jì)算,第一次計(jì)算的結(jié)果被保存,只要有可能,將被用作后續(xù)的計(jì)算,因此可從代碼中消除繁雜的計(jì)算。
4、 CASE/SWITCH語(yǔ)句優(yōu)化:將CASE/SWITCH語(yǔ)句作為跳轉(zhuǎn)表或跳轉(zhuǎn)串優(yōu)化。
5級(jí)優(yōu)化:
1、 全局公共子式消除:只要有可能,函數(shù)內(nèi)部相同的子表達(dá)式只計(jì)算一次。中間結(jié)果存入一個(gè)寄存器以代替新的計(jì)算。
2、 簡(jiǎn)單循環(huán)優(yōu)化:以常量占據(jù)一段內(nèi)存的循環(huán)再運(yùn)行時(shí)被優(yōu)化。
6級(jí)優(yōu)化:
1、 回路循環(huán):如果程序代碼能更快更有效地執(zhí)行,程序回路將進(jìn)行循環(huán)。
7級(jí)優(yōu)化:
1、 擴(kuò)展入口優(yōu)化:在適合時(shí)對(duì)寄存器變量使用DPTR數(shù)據(jù)指針,指針和數(shù)組訪問(wèn)被優(yōu)化以減小程序代碼和提高執(zhí)行速度。
8級(jí)優(yōu)化:
1、 公共尾部合并:對(duì)同一個(gè)函數(shù)有多處調(diào)用時(shí),一些設(shè)置代碼可被重復(fù)使用,從而減小程序代碼長(zhǎng)度。
9級(jí)優(yōu)化:
1、 公共子程序塊:檢測(cè)重復(fù)使用的指令序列,并將它們轉(zhuǎn)換為子程序。C51甚至?xí)匦掳才糯a以獲得更多的重復(fù)使用指令序列。
當(dāng)然,優(yōu)化級(jí)別并非越高越好,應(yīng)該根據(jù)具體要求適當(dāng)選擇。

Keil C51總線外設(shè)操作問(wèn)題的深入分析
    閱讀了《單片機(jī)與嵌入式系統(tǒng)應(yīng)用》2005年第10期雜志《經(jīng)驗(yàn)交流》欄目的一篇文章《Keil C51對(duì)同一端口的連續(xù)讀取方法》(原文)后,筆者認(rèn)為該文并未就此問(wèn)題進(jìn)行深入準(zhǔn)確的分析 文章中提到的兩種解決方法并不直接和簡(jiǎn)單。筆者認(rèn)為這并非是Keil C51中不能處理對(duì)一個(gè)端口進(jìn)行連續(xù)讀寫(xiě)的問(wèn)題,而是對(duì)Kei1 C51的使用不夠熟悉和設(shè)計(jì)不夠細(xì)致的問(wèn)題,因此特撰寫(xiě)本文。
    本文中對(duì)原文提到的問(wèn)題,提出了三種不同于原文的解決方法。每種方法都比原文中提到的方法更直接和簡(jiǎn)單,設(shè)計(jì)也更規(guī)范。(無(wú)意批評(píng),請(qǐng)?jiān)淖髡咭?jiàn)諒)

1 問(wèn)題回顧和分析
    原文中提到:在實(shí)際工作中遇到對(duì)同一端口反復(fù)連續(xù)讀取,Keil C51編譯并未達(dá)到預(yù)期的結(jié)果。原文作者對(duì)C編譯出來(lái)的匯編程序進(jìn)行分析發(fā)現(xiàn),對(duì)同一端口的第二次讀取語(yǔ)句并未被編譯。但可惜原文作者并未分析沒(méi)有被編譯的原因,而是匆忙地采用一些不太規(guī)范的方法試驗(yàn)出了兩種解決辦法。
    對(duì)此問(wèn)題,翻閱Keil C51的手冊(cè)很容易發(fā)現(xiàn):KeilC51的編譯器有一個(gè)優(yōu)化設(shè)置,不同的優(yōu)化設(shè)置,會(huì)產(chǎn)生不同的編譯結(jié)果。一般情況缺省編譯優(yōu)化設(shè)置被設(shè)定為8級(jí)優(yōu)化,實(shí)際最高可設(shè)定為9級(jí)優(yōu)化:

1. Dead code elimination。
2.Data overlaying。
3.Peephole optimization。
4.Register variables。
5.Common subexpression elimination。
6.Loop rotation。
7.Extended Index Access Optimizing。
8.Reuse Common Entry Code。
9.Common Block Subroutines。
    而以上的問(wèn)題,正是由于Keil C51編譯優(yōu)化產(chǎn)生的。因?yàn)樵谠某绦蛑袑⑼庠O(shè)地址直接按如下定義:
unsigned char xdata MAX197 _at_ 0x8000
    采用_at_將變量MAX197定義到外部擴(kuò)展RAM 指定地址0x8000。因此,Keil C51優(yōu)化編譯理所當(dāng)然認(rèn)為重復(fù)讀第二次是沒(méi)有用的,直接用第一次讀取的結(jié)果就可以了,因此編譯器跳過(guò)了第二條讀取語(yǔ)句。至此,問(wèn)題就一目了然了。

2 解決方法
由以上分析很容易就能提出很好的解決辦法。
2.1 最簡(jiǎn)單最直接的辦法
    程序一點(diǎn)都不用修改,將Keil C51的編譯優(yōu)化選擇設(shè)置為0(不優(yōu)化)就可以了。選擇project窗口的Target,然后打開(kāi)“Options for Target”設(shè)置對(duì)話框,選擇“C51”選項(xiàng)卡,將“Code Optimiztaion”中的“Level”選擇為“0:Costant folding”。再次編譯后,大家會(huì)發(fā)現(xiàn)編譯結(jié)果為:
CLR MAXHBEN
MOV DPTR,#MAX197
MOVX A,@DPTR
MOV R7,A
MOV down8,R7
SETB MAXHBEN
MOV DPTR,#MAX197
MOVX A,@DPTR
MOV R7,A
MOV up4,R7
兩次讀取操作都被編譯出來(lái)了。

2.2 最好的方法
    告訴Keil C51,這個(gè)地址不是一般的擴(kuò)展RAM,而是連接的設(shè)備,具有“揮發(fā)”特性,每次讀取都是有意義的。可以修改變量定義,增加“volatile”關(guān)鍵字說(shuō)明其特征:
unsigned char volatile xdata MAX197 _at_ 0x8000;
    也可以在程序中包含系統(tǒng)頭文件;“#include<absacc.h>”,然后在程序中修改變量,定義為直接地址:
#define MAX197 XBYTE
    這樣,Keil C51的設(shè)置仍然可以保留高級(jí)優(yōu)化,且編譯結(jié)果中,同樣兩次讀取并不會(huì)被優(yōu)化跳過(guò)。

2 3 硬件解決方法
    原文中將MAX197的數(shù)據(jù)直接連接到數(shù)據(jù)總線,而對(duì)地址總線并未使用,采用一根端口線選擇操作高低字節(jié)。很簡(jiǎn)單的修改方法就是使用一根地址線選擇操作高低字節(jié)即可。比如:將P2.0(A8)連接到原來(lái)P1.0連接的HBEN腳(MAX197的5腳).在程序中分別定義高低字節(jié)的操作地址:
unsigned char volatile xdata MAX197_L _at_ 0x8000;
unsigned char volatile xdata MAX197_H _at_ 0x8100;
將原來(lái)的程序:
MAXHBEN =0;
down8=MAX197;//讀取低8位
MAXHBEN =1;
up4=MAX197;//讀取高4位
改為以下兩句即可
down8= MAX197_L;//讀取低8位
up4=MAX197_H;//讀取高4位

3 小結(jié)
    Keil C51經(jīng)過(guò)長(zhǎng)期考驗(yàn)和改進(jìn)以及大量開(kāi)發(fā)人員的實(shí)際使用,已經(jīng)克服了絕大多數(shù)的問(wèn)題,并且其編譯效率也非常高。對(duì)于一般的使用.很難再發(fā)現(xiàn)什么問(wèn)題。筆者曾經(jīng)粗略研究過(guò)一下Keil C51優(yōu)化編洋的結(jié)果.非常佩服Keil C51設(shè)計(jì)者的智慧,一些C程序編譯產(chǎn)生的匯編代碼.甚至比一般程序員直接用匯編編寫(xiě)的代碼還要優(yōu)秀和簡(jiǎn)練 通過(guò)研讀Kell C51編譯產(chǎn)生的匯編代碼.對(duì)提高匯編語(yǔ)言編寫(xiě)程序的水平都是很有幫助的。
    由本文中的問(wèn)題可以看出:在設(shè)計(jì)中遇到問(wèn)題時(shí).一定不要被表面現(xiàn)象蒙蔽,不要急于解決,應(yīng)該認(rèn)真分析,找出問(wèn)題的原因.這樣才能從根本上徹底解決問(wèn)題。

附表:Keil C51中的優(yōu)化級(jí)別及優(yōu)化作用 級(jí)別         說(shuō)明
0         常數(shù)合并:編譯器預(yù)先計(jì)算結(jié)果,盡可能用常數(shù)代替表達(dá)式。包括運(yùn)行地址計(jì)算。
優(yōu)化簡(jiǎn)單訪問(wèn):編譯器優(yōu)化訪問(wèn)8051系統(tǒng)的內(nèi)部數(shù)據(jù)和位地址。
跳轉(zhuǎn)優(yōu)化:編譯器總是擴(kuò)展跳轉(zhuǎn)到最終目標(biāo),多級(jí)跳轉(zhuǎn)指令被刪除。
1         死代碼刪除:沒(méi)用的代碼段被刪除。
拒絕跳轉(zhuǎn):嚴(yán)密的檢查條件跳轉(zhuǎn),以確定是否可以倒置測(cè)試邏輯來(lái)改進(jìn)或刪除。
2         數(shù)據(jù)覆蓋:適合靜態(tài)覆蓋的數(shù)據(jù)和位段被確定,并內(nèi)部標(biāo)識(shí)。BL51連接/定位器可以通過(guò)全局?jǐn)?shù)據(jù)流分析,選擇可被覆蓋的段。
3         窺孔優(yōu)化:清除多余的MOV指令。這包括不必要的從存儲(chǔ)區(qū)加載和常數(shù)加載操作。當(dāng)存儲(chǔ)空間或執(zhí)行時(shí)間可節(jié)省時(shí),用簡(jiǎn)單操作代替復(fù)雜操作。
4         寄存器變量:如有可能,自動(dòng)變量和函數(shù)參數(shù)分配到寄存器上。為這些變量保留的存儲(chǔ)區(qū)就省略了。
優(yōu)化擴(kuò)展訪問(wèn):IDATA、XDATA、PDATA和CODE的變量直接包含在操作中。在多數(shù)時(shí)間沒(méi)必要使用中間寄存器。
局部公共子表達(dá)式刪除:如果用一個(gè)表達(dá)式重復(fù)進(jìn)行相同的計(jì)算,則保存第一次計(jì)算結(jié)果,后面有可能就用這結(jié)果。多余的計(jì)算就被刪除。
Case/Switch優(yōu)化:包含SWITCH和CASE的代碼優(yōu)化為跳轉(zhuǎn)表或跳轉(zhuǎn)隊(duì)列。
5         全局公共子表達(dá)式刪除:一個(gè)函數(shù)內(nèi)相同的子表達(dá)式有可能就只計(jì)算一次。中間結(jié)果保存在寄存器中,在一個(gè)新的計(jì)算中使用。
簡(jiǎn)單循環(huán)優(yōu)化:用一個(gè)常數(shù)填充存儲(chǔ)區(qū)的循環(huán)程序被修改和優(yōu)化。
6         循環(huán)優(yōu)化:如果結(jié)果程序代碼更快和有效則程序?qū)ρh(huán)進(jìn)行優(yōu)化。
7         擴(kuò)展索引訪問(wèn)優(yōu)化:適當(dāng)時(shí)對(duì)寄存器變量用DPTR。對(duì)指針和數(shù)組訪問(wèn)進(jìn)行執(zhí)行速度和代碼大小優(yōu)化。
8         公共尾部合并:當(dāng)一個(gè)函數(shù)有多個(gè)調(diào)用,一些設(shè)置代碼可以復(fù)用,因此減少程序大小。
9         公共塊子程序:檢測(cè)循環(huán)指令序列,并轉(zhuǎn)換成子程序。Cx51甚至重排代碼以得到更大的循環(huán)序列。

優(yōu)化論

談到優(yōu)化,其實(shí)很多人都哭笑不得,因?yàn)樵谝粋(gè)C51軟件工程師的生涯中,總要被KEIL的優(yōu)化耍那么一次到幾次。我被耍過(guò),想必看著文章的你也被耍過(guò),如果你回答說(shuō)不,那只能說(shuō)你寫(xiě)的C51程序不多!
看看KEILC的優(yōu)化級(jí)別選項(xiàng)吧:

0-9共10個(gè)級(jí)別的優(yōu)化,0是最低,9最高,一個(gè)普通的程序,設(shè)置最高級(jí)別和最低級(jí)別,編譯后代碼量有時(shí)會(huì)相差很遠(yuǎn),以DX板DEMO程序?yàn)槔?0級(jí)優(yōu)化后是14K的CODE,9級(jí)優(yōu)化后是10K的CODE,前后相差了4K。可見(jiàn)這個(gè)差別是多么的大。
事實(shí)上我們不需要知道對(duì)應(yīng)的各個(gè)級(jí)別KEIL會(huì)如何優(yōu)化你的程序或優(yōu)化了些什么,我們只需要以一種嚴(yán)謹(jǐn)?shù)膽B(tài)度去編寫(xiě)和對(duì)待你的程序就可以了。在我個(gè)人的觀念中,程序在9級(jí)優(yōu)化后依然能保持完美無(wú)誤的運(yùn)行,你才算了解KEIL的脾氣。
好了,還是說(shuō)點(diǎn)正點(diǎn)的:
有些人習(xí)慣整體程序都選擇同一個(gè)優(yōu)化級(jí),事實(shí)上每個(gè)C文件都可以有獨(dú)立的優(yōu)化級(jí)別的:
在工作區(qū)右鍵選擇你的模塊(.C)然后選取Options for File xxx就會(huì)出現(xiàn)如下界面:

在C51選項(xiàng)中就可以選擇優(yōu)化級(jí)別和警告級(jí)別等東西了,被獨(dú)立設(shè)置過(guò)的C文件會(huì)有特殊的標(biāo)記的:

用以提醒你這個(gè)文件的編譯處理并非默認(rèn)設(shè)置!
如果你覺(jué)得模塊優(yōu)化都不夠細(xì)的話,你可以考慮局部?jī)?yōu)化,也就是說(shuō)對(duì)某個(gè)函數(shù)實(shí)行某個(gè)級(jí)別的優(yōu)化。當(dāng)你發(fā)現(xiàn)9級(jí)優(yōu)化的時(shí)候某個(gè)函數(shù)總是變的不正常,但你又希望其它函數(shù)和程序段保持最高的簡(jiǎn)潔度,那么局部?jī)?yōu)化可以說(shuō)是相當(dāng)有用的了。在KEIL手冊(cè)中有介紹這個(gè)功能:
#pragma OPTIMIZE(x) x就是你希望的優(yōu)化級(jí)別,一般應(yīng)用如下:
#pragma OPTIMIZE(6)
void FunA()
{
}
......
......

#pragma OPTIMIZE(9)
void FunB()
{
}
上面的意思就是說(shuō),在void FunA()到void FunB()之前的所有函數(shù),包括FunA在內(nèi),都采用6級(jí)的優(yōu)化,而從FunB開(kāi)始直到之后,只要沒(méi)碰上#pragma OPTIMIZE,都采用9級(jí)優(yōu)化了。
OPTIMIZE還可以多一個(gè)參數(shù),就是speed和size,
用法: #pragma OPTIMIZE(9,speed)或#pragma OPTIMIZE(5,size)
對(duì)應(yīng)的就是9級(jí)優(yōu)化,以速度為主,或5級(jí)優(yōu)化,以空間最小為主。

4.StartUp.a51
在之前第一節(jié)的建立工程中就曾經(jīng)提到過(guò)StartUp.a51這個(gè)東西了,就是在工程初建的時(shí)候有個(gè)對(duì)話框用于選擇是否為工程添加這個(gè)a51文件。

其實(shí)這個(gè)文件給大家最最深刻的感覺(jué)就是:開(kāi)機(jī)清空RAM。事實(shí)上它還有其他特別的用途的,例如初始化堆棧(很多人不知道KEILC一開(kāi)始把堆棧設(shè)定為多少,事實(shí)上可以通過(guò)軟件仿真的時(shí)候從這個(gè)文件找到答案),然后是再入函數(shù)的虛擬堆棧的設(shè)置,還有更高級(jí)一點(diǎn)的,BANK的初始化。
舊版本KEIL自動(dòng)為每個(gè)工程默認(rèn)添加相同的StartUp文件,后期的KEIL就有了上圖的選擇,如果選擇添加,則會(huì)為每個(gè)工程添加一個(gè)獨(dú)立的StartUp。用戶可以通過(guò)手工改寫(xiě)StartUp.a51實(shí)現(xiàn)某些必要的上電初始化。例如最通常的:取消單片機(jī)開(kāi)機(jī)清RAM功能!!
關(guān)于STARTUP的介紹,我建議大家看看以下的文章,它的解釋非常詳盡。
##################################
在實(shí)際使用時(shí)發(fā)現(xiàn)仿真時(shí)有寫(xiě)程序是白色的無(wú)法進(jìn)行斷點(diǎn)設(shè)置
搜索到的答案是優(yōu)化等級(jí)過(guò)高,一些普通的程序被優(yōu)化。
只得把優(yōu)化程序等級(jí)降低。
關(guān)閉窗口
主站蜘蛛池模板: 精品少妇一区二区三区日产乱码 | 操视频网站| 围产精品久久久久久久 | 国产日韩av一区二区 | 国产欧美精品一区二区色综合朱莉 | 亚洲精品字幕 | 黄视频国产 | 日韩在线不卡视频 | 中文在线播放 | 久久久网| 日韩精品一区二区三区高清免费 | 在线观看日本高清二区 | 久草中文网 | 中文字幕一区二区三区在线观看 | 久久亚洲国产精品 | 成人免费观看男女羞羞视频 | 91精品国产91| 久久视频免费观看 | 日本一区二区三区四区 | 蜜桃传媒av | 玖玖视频 | 亚洲日本乱码在线观看 | 色偷偷噜噜噜亚洲男人 | 精品在线视频播放 | 97国产在线观看 | 亚洲精品久久久久久久久久久 | h网站在线观看 | eeuss国产一区二区三区四区 | 日韩在线小视频 | 免费在线观看av网址 | 伊人狠狠 | 国产精品日韩欧美一区二区三区 | 91视频国产精品 | 激情久久久久 | 中文字幕av一区 | 日韩中文字幕一区二区 | 亚洲精品粉嫩美女一区 | 欧美激情欧美激情在线五月 | 99久久精品国产毛片 | 国产精品久久精品 | 在线色网|