學習如何高效率編寫單片機代碼,優化程序設計


1、 使用盡量小的數據類型

能用unsiged就不用signed;能用char就不用int;能不用floating就不用;能用位操作不用算數。

 

2、使用自加、自減指令

通常使用自加、自減指令和復合賦值表達式(如a-=1 及a+=1 等)都能夠生成高質量的程序代碼,編譯器通常都能夠生成inc 和dec 之類的指令,而使用a=a+1 或a=a-1 之類的指令,有很多C 編譯器都會生成二到三個字節的指令。

 

3、減少運算的強度

可以使用運算量小但功能相同的表達式替換原來復雜的的表達式。

(1) 求余運算(條件是除數必須是2的n次冪才行)

N= N %8 可以改為N = N &7

9%8=1
1001 & (1000 - 1=1001 & 0111
=1 // 1001是9的二進制表示,1000是8的二進制表示,8(2的3次冪)

說明:位操作只需一個指令周期即可完成,而大部分的C 編譯器的“%”運算均是調用子程序來完成,代碼長、執行速度慢。通常,只要求是求2n 方的余數,均可使用位操作的方法來代替。

 

(2) 平方運算

N=Pow(3,2) 可以改為N=3*3

說明:在有內置硬件乘法器的單片機中(如51 系列),乘法運算比求平方運算快得多, 因為浮點數的求平方是通過調用子程序來實現的,乘法運算的子程序比平方運算的子程序代碼短,執行速度快。

 

(3) 用位移代替乘法除法

N=M*8 可以改為N=M<<3,N=M/8 可以改為N=M>>3

說明:通常如果需要乘以或除以2n,都可以用移位的方法代替。如果乘以2n,都可以生成左移的代碼,而乘以其它的整數或除以任何數,均調用乘除法子程序。用移位的方法得到代碼比調用乘除法子程序生成的代碼效率高。實際上,只要是乘以或除以一個整數,均可以用移位的方法得到結果。

如N=M*9可以改為N=(M<<3)+M;

 

 

(4)函數和宏函數的區別

宏函數占用了大量的空間,而函數占用了時間。函數調用是要使用系統的棧來保存數據的,如果編譯器里有棧檢查選項,一般在函數的頭會嵌入一些匯編語句對當前棧進行檢查;同時,CPU也要在函數調用時保存和恢復當前的現場,進行壓棧和彈棧操作,所以,函數調用需要一些CPU時間。而宏函數不存在這個問題。宏函數僅僅作為預先寫好的代碼嵌入到當前程序,不會產生函數調用,所以僅僅是占用了空間,在頻繁調用同一個宏函數的時候,該現象尤其突出。

 

 

4、循環

(1)、循環語

對於一些不需要循環變量參加運算的任務可以把它們放到循環外面,這里的任務包括表達式、函數的調用、指針運算、數組訪問等,應該將沒有必要執行多次的操作全部集合在一起,放到一個init的初始化程序中進行。

(2)、延時函數:

通常使用的延時函數均采用自加的形式:

兩個函數的延時效果相似,但幾乎所有的C編譯對后一種函數生成的代碼均比前一種代碼少1~3個字節,因為幾乎所有的MCU均有為0轉移的指令,采用后一種方式能夠生成這類指令。在使用while循環時也一樣,使用自減指令控制循環會比使用自加指令控制循環生成的代碼更少1~3個字母。但是在循環中有通過循環變量"i"讀寫數組的指令時,使用預減循環時有可能使數組超界,要引起注意。

(3)while循環和do…while循環

用while循環時有以下兩種循環形式:

在這兩種循環中,使用do…while循環編譯后生成的代碼的長度短於while循環。

 

5、其它

比如使用在線匯編及將字符串和一些常量保存在程序存儲器中,均有利於優化。

 

 6、i++ 和++i 的區別

void test1(void)
{
    int i,x;
    i = 1;
    x = 1;
    x = i++;                     //先讓x變成i的值1,再讓i加1
    printf("test1 x:%d\r\n", x);     //x=1
    printf("test1 i:%d\r\n", i);     //i=2
}

void test2(void)
{
    int i,x;
    i = 1;
    x = 1;
    x = ++i;                            //先讓i加1, 再讓x變成i的值2
    printf("test2 x:%d\r\n", x);    //x=2
    printf("test2 i:%d\r\n", i);    //i=2
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM