• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      基于Keil C51編譯器的程序優(yōu)化

      2014-08-27 08:12:52
      時代農(nóng)機 2014年2期
      關(guān)鍵詞:編譯器數(shù)據(jù)類型存儲器

      徐 斯

      (湖南機電職業(yè)技術(shù)學(xué)院,湖南 長沙 410151)

      80C51單片機是目前國內(nèi)外工業(yè)測控領(lǐng)域中使用極為廣泛的一類8位MCU,C51是面向80C51單片機的C語言。C語言是一種結(jié)構(gòu)化的程序設(shè)計高級語言,在單片機應(yīng)用系統(tǒng)開發(fā)中采用C語言編程,易于開發(fā)復(fù)雜的單片機應(yīng)用程序,易于進行單片機應(yīng)用程序的移植,有利于產(chǎn)品中的單片機重新選型,可大大加快單片機應(yīng)用程序的開發(fā)速度。用C51編寫的應(yīng)用程序須經(jīng)C51編譯器轉(zhuǎn)換生成單片機可執(zhí)行的代碼程序。Keil C51編譯器生成的代碼緊湊、使用方便、全面支持8051單片機主流產(chǎn)品及其眾多的派生系列。

      1 靈活選擇變量的存儲器類型和數(shù)據(jù)類型

      (1)變量的數(shù)據(jù)類型選擇。①盡可能使用最小的數(shù)據(jù)類型char、unsigned char或bit。這類數(shù)據(jù)只占用1B或者1位,由于80C51是8位機,顯然對它們的操作要比對int或long類型數(shù)據(jù)操作要方便得多。②盡可能使用unsigned數(shù)據(jù)類型,原因是80C51機器指令不支持符號運算。當在C源代碼中使用了有符號的變量,盡管從字面上看,其操作十分簡單,但C51編譯器將要增加相應(yīng)的庫函數(shù),產(chǎn)生更多的程序代碼去處理符號運算。所以除了根據(jù)變量長度來選擇變量類型以外,還要考慮該變量是否會用于負數(shù)的場合,如果程序中可以不需要負數(shù),那么可把變量都定義成無符號類型的。

      (2)變量的存儲器類型選擇。由于單片機系統(tǒng)的存儲器資源有限,為了提高執(zhí)行效率,對存儲器類型的設(shè)定,應(yīng)該根據(jù)以下原則:只要條件滿足,盡量先使用直接尋址片內(nèi)數(shù)據(jù)存儲器(data),其次設(shè)定變量為間接尋址片內(nèi)數(shù)據(jù)存儲器(idata),在內(nèi)部存儲器數(shù)量不夠的情況下,才使用外部存儲器,而且在外部存儲器中,優(yōu)先選擇分頁尋址的數(shù)據(jù)存儲器pdata,最后才是片外數(shù)據(jù)存儲器xdata,而且,在內(nèi)部和外部存儲器共同使用的情況下,要合理分配存儲器,對經(jīng)常使用和計算頻繁的數(shù)據(jù),應(yīng)該使用內(nèi)部存儲器,其他的則使用外部存儲器。根據(jù)它們的數(shù)量進行分配,盡量減少訪問外部存儲器,從而提高程序運行效率。

      2 避免使用浮點變量

      在80C51單片機系統(tǒng)上使用32位浮點數(shù)是得不償失的,這樣做會浪費單片機大量的存儲器資源和程序執(zhí)行時間。一定要在系統(tǒng)中使用浮點數(shù)的時候,可以通過提高數(shù)值數(shù)量級或使用整型運算代替浮點運算。在運算時,可以進行定點運算的盡量進行定點運算,避免進行浮點運算。盡量減少乘除法運算,如*2或/2,就可以使用移位操作代替乘除法運算,這樣不僅可以減少代碼量,同時還能大提高程序執(zhí)行效率。處理ints和longs比處理doubles和floats要方便得多,代碼執(zhí)行起來會更快,C51編譯器也不用連接處理浮點運算的模塊。

      3 盡可能使用局部變量

      一個源文件可以包含一個或幾個函數(shù)。在一個函數(shù)內(nèi)部定義的變量是局部,它只在本函數(shù)范圍內(nèi)有效。在函數(shù)之外定義的變量是全局變量,它可以為本源文件中其它函數(shù)所共用,有效范圍為:從定義變量的位置開始到本源文件結(jié)束。

      在編寫C51語言程序時,不是特別必要的地方一般不要使用全局變量,而盡可能地使用局部變量,因為:

      (1)局部變量只是在使用它時,編譯器才為它在內(nèi)部存儲區(qū)分配存儲單元,而全局變量在程序的全部執(zhí)行過程中都要占用存儲單元。

      (2)全局變量使函數(shù)的通用性降低了,因為函數(shù)在執(zhí)行時要依賴于其所在的外部變量。如果將一個函數(shù)移到另一個文件中,還要將有關(guān)的外部變量及其值一起移過去。但若該外部變量與其它文件的變量同名時,就會出現(xiàn)問題,降低了程序的可靠性和通用性。在程序設(shè)計中,在劃分模塊時要求模塊的“內(nèi)聚性”強、與其它模塊的“耦合性”弱。即模塊功能要單一(不要把許多互不相干的功能放到一個模塊中),與其它模塊的相互影響盡量少。而全局變量是不符合這個原則的。一般要求把C51程序中的函數(shù)做成一個封閉體,除了可以通過“實參——形參”的渠道與外界發(fā)生聯(lián)系外,沒有其它渠道。這樣的程序移植性好、可讀性強。

      (3)使用全局變量過多,會降低程序的清晰性,人們往往難以清楚地判斷出每個瞬時各個外部變量的值。在各個函數(shù)執(zhí)行時都可能改變外部變量的值,程序容易出錯。因此,要限制使用全局變量。

      4 使用庫函數(shù)

      從用戶的角度來看,有兩種函數(shù):庫函數(shù)和用戶自定義函數(shù)。庫函數(shù)是KeilC51編譯器提供的,不需要用戶進行定義,可以直接調(diào)用。用戶自定義函數(shù)是用戶根據(jù)自己需要編寫的能實現(xiàn)特定功能的函數(shù),它必須先進行定義之后才能調(diào)用。正確而靈活地使用庫函數(shù)可使程序代碼簡單、結(jié)構(gòu)清晰、易于調(diào)試和維護。

      (1)重視本征庫函數(shù)的使用。本征庫函數(shù)是庫函數(shù)中的一類,它在編譯時直接將固定的代碼插入到當前行,而不是用匯編語言中的“ACALL”和“LCALL”指令來實現(xiàn)調(diào)用,從而大大提高了函數(shù)的訪問效率。

      例如單字節(jié)循環(huán)位移指令RL A和RR A相對的調(diào)令是_crol_(循環(huán)左移)和_cror_(循環(huán)右移)。如果想對int或long類型的變量進行循環(huán)位移,匯編調(diào)令將更加復(fù)雜,而且執(zhí)行的時間會更長。對于int類型C庫函數(shù)為_irol_、iror_,對于long類型函數(shù)為_lrol_、_lror_。再例如JBC指令相對的調(diào)令是_testbit_,如果參數(shù)位置位,它將返回1;否則將返回0。

      (2)重視復(fù)制、比較、移動等子符串處理庫函數(shù)的使用。子符串處理庫函數(shù)位于string.h中,其中包括復(fù)制、比較、移動等函數(shù):memccpy、memchr、memcmp、memcpy、memmove、memset。在這些函數(shù)中,字符串的長度由調(diào)用者明確規(guī)定,函數(shù)可以工作在任何模式下。使用這些函數(shù)可以很方便地對字符串進行處理。

      例1:使用庫函數(shù)對字符串進行復(fù)制、比較、移動。

      5 使用宏替代無符號數(shù)據(jù)類型和函數(shù)

      (1)使用宏替代無符號數(shù)據(jù)類型。在輸入源程序時,為了提高輸入效率,可使用宏替代無符號數(shù)據(jù)類型。其方法是在源程序開頭,使用#define語句定義。

      例 2:#define uchar unsigned char

      這樣,在輸入源程序時,可以 uchar、uint、ulong代替unsigned char、unsigned int、unsigned long。在后面的敘述中我們有可能不加說明地使用uchar、uint、ulong說明定義的變量。

      (2)使用宏替代函數(shù)。對于小段代碼,像從鎖存器中讀取數(shù)據(jù),可通過使用宏來替代函數(shù),使得程序有更好的可讀性,可把代碼定義在宏中,這樣看上去更像函數(shù)編譯器在碰到宏時,按照事先定義的代碼去替代宏。宏的名字應(yīng)能夠描述宏的操作,當需改變宏時,只要修改宏定義處即可。

      例3:#define led_on(){

      宏能夠使得訪問多層結(jié)構(gòu)和數(shù)組更加容易,可以用宏替代程序中經(jīng)常使用的復(fù)雜語句,以減少程序輸入時的工作量,且有更好的可讀性和可維護性,與函數(shù)調(diào)用相比較,執(zhí)行效率更高,但程序的執(zhí)行代碼較大,因編譯器將定義的宏內(nèi)容直接嵌入到代碼中。

      6 盡量使用小存儲模式

      C51提供了三種存儲器模式存儲變量、過程參數(shù)和分配再入函數(shù)堆棧。應(yīng)該盡量使用小存儲器模式,即SMALL模式。應(yīng)用系統(tǒng)很少需要使用其他兩種模式,像有大的再入函數(shù)堆棧系統(tǒng)那樣。一般來說如果系統(tǒng)所需要的內(nèi)存數(shù)小于內(nèi)部RAM數(shù)時,都應(yīng)以小存儲模式進行編譯,對其它存儲模式可以由PDATA和XDATA進行說明。

      在SMALL模式下,DATA段是所有的內(nèi)部變量和全局變量的默認存儲段,所有參數(shù)傳遞都發(fā)生在DATA段中。如果有函數(shù)被聲明為再入函數(shù),編譯器會在內(nèi)部RAM中為它們分配空間。這種模式的優(yōu)勢就是數(shù)據(jù)的存取速度很快,但由于片內(nèi)RAM空間有限,對于較大的程序還得采用LARGE存儲器模式。

      在實際進行項目開發(fā)時,如果能遵守科學(xué)的工程開發(fā)規(guī)則,靈活地運用C語言的強大功能,熟悉硬件特點,就能夠在較短時間內(nèi)編寫出高效率、高可靠、易維護的嵌入式系統(tǒng)的執(zhí)行代碼。

      7 使用C51和匯編語言的混合編程

      在模塊化程序開發(fā)過程中,一般用匯編語言編寫與硬件有關(guān)的程序,用C51語言編寫主程序及數(shù)據(jù)處理程序。使用混合編程技術(shù)可以很方便地在一些較大的C51程序中加入已有的匯編驅(qū)動程序。在編寫較大的程序時利用已有的匯編程序一方面可以節(jié)約大量的程序開發(fā)時間,另一方面在編寫驅(qū)動程序時,使用匯編語言可以保證部分對時間和穩(wěn)定性有嚴格要求的程序段。同時,混合編程中的C51和匯編語言的使用仍然和獨立開發(fā)時基本一樣,只是在使用不同的語言時,需要注意不同函數(shù)之間的調(diào)用格式和參數(shù)傳遞的規(guī)定。

      在實際進行項目開發(fā)時,如果能遵守科學(xué)的工程開發(fā)規(guī)則,靈活地運用C語言的強大功能,熟悉硬件特點,就能夠在較短時間內(nèi)編寫出高效率、高可靠、易維護的嵌入式系統(tǒng)的執(zhí)行代碼。

      [1]譚浩強.C程序設(shè)計(第三版)[M].北京:清華大學(xué)出版社,2005.

      [2]李廣弟.單片機基礎(chǔ)[M].北京:北京航空航天大學(xué)出版社,2007.

      [3]張齊,杜群貴.單片機應(yīng)用系統(tǒng)設(shè)計技術(shù)-基于C語言編程[M].北京:電子工業(yè)出版社,2004.

      [4]徐愛鈞.8051單片機實踐教程-asm51匯編語言與C51高級語言應(yīng)用[M].北京:電子工業(yè)出版社,2005.

      [5]楊恢先.單片機原理及應(yīng)用[M].湘潭:湘潭大學(xué)出版社,2013.

      [6]施大發(fā).基于Keil C51編譯器的程序優(yōu)化設(shè)計[J].電腦編程技巧與維護,2010,(2).

      猜你喜歡
      編譯器數(shù)據(jù)類型存儲器
      詳談Java中的基本數(shù)據(jù)類型與引用數(shù)據(jù)類型
      靜態(tài)隨機存儲器在軌自檢算法
      如何理解數(shù)據(jù)結(jié)構(gòu)中的抽象數(shù)據(jù)類型
      基于相異編譯器的安全計算機平臺交叉編譯環(huán)境設(shè)計
      存儲器——安格爾(墨西哥)▲
      通用NC代碼編譯器的設(shè)計與實現(xiàn)
      基于Nand Flash的高速存儲器結(jié)構(gòu)設(shè)計
      編譯器無關(guān)性編碼在微控制器中的優(yōu)勢
      基于ARM嵌入式平臺的x86譯碼SOC架構(gòu)設(shè)計
      一種存儲器容錯設(shè)計方法
      迭部县| 读书| 巴楚县| 邳州市| 长岭县| 宜昌市| 开封市| 双峰县| 乐山市| 云龙县| 三亚市| 晋宁县| 喀喇沁旗| 汕头市| 文水县| 广安市| 兰考县| 徐水县| 平南县| 石城县| 福建省| 新绛县| 敖汉旗| 岳池县| 洛阳市| 藁城市| 蒲江县| 庆安县| 深泽县| 繁昌县| 洪雅县| 蓬莱市| 焉耆| 来安县| 宝兴县| 波密县| 巢湖市| 晋江市| 巨鹿县| 花莲县| 常熟市|