由于單片機(jī)的性能同電腦的性能是天淵之別的,無論從空間資源上、內(nèi)存資源、工作頻率,都是無法

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:域名注冊、網(wǎng)絡(luò)空間、營銷軟件、網(wǎng)站建設(shè)、尼開遠(yuǎn)網(wǎng)站維護(hù)、網(wǎng)站推廣。
與之比較的。PC 機(jī)編程基本上不用考慮空間的占用、內(nèi)存的占用的問題,最終目的就是實(shí)現(xiàn)功能就可以了。
對于單片機(jī)來說就截然不同了,一般的單片機(jī)的Flash 和Ram 的資源是以KB 來衡量的,可想而知,單片
機(jī)的資源是少得可憐,為此我們必須想法設(shè)法榨盡其所有資源,將它的性能發(fā)揮到最佳,程序設(shè)計時必須
遵循以下幾點(diǎn)進(jìn)行優(yōu)化:
1. 使用盡量小的數(shù)據(jù)類型
能夠使用字符型(char)定義的變量,就不要使用整型(int)變量來定義;能夠使用整型變量定義的變
量就不要用長整型(long int),能不使用浮點(diǎn)型(float)變量就不要使用浮點(diǎn)型變量。當(dāng)然,在定義變
量后不要超過變量的作用范圍,如果超過變量的范圍賦值,C 編譯器并不報錯,但程序運(yùn)行結(jié)果卻錯了,
而且這樣的錯誤很難發(fā)現(xiàn)。
2. 使用自加、自減指令
通常使用自加、自減指令和復(fù)合賦值表達(dá)式(如a-=1 及a+=1 等)都能夠生成高質(zhì)量的
程序代碼,編譯器通常都能夠生成inc 和dec 之類的指令,而使用a=a+1 或a=a-1 之類
的指令,有很多C 編譯器都會生成二到三個字節(jié)的指令。
3. 減少運(yùn)算的強(qiáng)度
可以使用運(yùn)算量小但功能相同的表達(dá)式替換原來復(fù)雜的的表達(dá)式。
(1) 求余運(yùn)算
N= N %8 可以改為N = N 7
說明:位操作只需一個指令周期即可完成,而大部分的C 編譯器的“%”運(yùn)算均是調(diào)用子程序來
完成,代碼長、執(zhí)行速度慢。通常,只要求是求2n 方的余數(shù),均可使用位操作的方法來代替。
(2) 平方運(yùn)算
N=Pow(3,2) 可以改為N=3*3
說明:在有內(nèi)置硬件乘法器的單片機(jī)中(如51 系列),乘法運(yùn)算比求平方運(yùn)算快得多, 因為浮點(diǎn)數(shù)
的求平方是通過調(diào)用子程序來實(shí)現(xiàn)的,乘法運(yùn)算的子程序比平方運(yùn)算的子程序代碼短,執(zhí)行速度快。
(3) 用位移代替乘法除法
N=M*8 可以改為N=M3
N=M/8 可以改為N=M3
說明:通常如果需要乘以或除以2n,都可以用移位的方法代替。如果乘以2n,都可以生成左移
的代碼,而乘以其它的整數(shù)或除以任何數(shù),均調(diào)用乘除法子程序。用移位的方法得到代碼比調(diào)用乘除法子
程序生成的代碼效率高。實(shí)際上,只要是乘以或除以一個整數(shù),均可以用移位的方法得到結(jié)果。如N=M*9
可以改為N=(M3)+M;
(4) 自加自減的區(qū)別
例如我們平時使用的延時函數(shù)都是通過采用自加的方式來實(shí)現(xiàn)。
void DelayNms(UINT16 t)
{
UINT16 i,j;
for(i=0;it;i++)
for(j=0;i1000;j++)
}
可以改為
void DelayNms(UINT16 t)
{
UINT16 i,j;
for(i=t;i=0;i--)
for(j=1000;i=0;j--)
}
說明:兩個函數(shù)的延時效果相似,但幾乎所有的C 編譯對后一種函數(shù)生成的代碼均比前一種代碼少1~3
個字節(jié),因為幾乎所有的MCU 均有為0 轉(zhuǎn)移的指令,采用后一種方式能夠生成這類指令。
4. while 與do...while 的區(qū)別
void DelayNus(UINT16 t)
{
while(t--)
{
NOP();
}
}
可以改為
void DelayNus(UINT16 t)
{
do
{
NOP();
}while(--t)
}
說明:使用do…while 循環(huán)編譯后生成的代碼的長度短于while 循環(huán)。
5. register 關(guān)鍵字
void UARTPrintfString(INT8 *str)
{
while(*str str)
{
UARTSendByte(*str++)
}
}
可以改為
void UARTPrintfString(INT8 *str)
{
register INT8 *pstr=str;
while(*pstr pstr)
{
UARTSendByte(*pstr++)
}
}
說明:在聲明局部變量的時候可以使用register 關(guān)鍵字。這就使得編譯器把變量放入一個多用途的寄存
器中,而不是在堆棧中,合理使用這種方法可以提高執(zhí)行速度。函數(shù)調(diào)用越是頻繁,越是可能提高代碼的
速度,注意register 關(guān)鍵字只是建議編譯器而已。
6. volatile 關(guān)鍵字
volatile 總是與優(yōu)化有關(guān),編譯器有一種技術(shù)叫做數(shù)據(jù)流分析,分析程序中的變量在哪里賦值、在
哪里使用、在哪里失效,分析結(jié)果可以用于常量合并,常量傳播等優(yōu)化,進(jìn)一步可以死代碼消除。一般來
說,volatile 關(guān)鍵字只用在以下三種情況:
a) 中斷服務(wù)函數(shù)中修改的供其它程序檢測的變量需要加volatile(參考本書高級實(shí)驗程序)
b) 多任務(wù)環(huán)境下各任務(wù)間共享的標(biāo)志應(yīng)該加volatile
c) 存儲器映射的硬件寄存器通常也要加volatile 說明,因為每次對它的讀寫都可能由不同意義
總之,volatile 關(guān)鍵字是一種類型修飾符,用它聲明的類型變量表示可以被某些編譯器未知的因素
更改,比如:操作系統(tǒng)、硬件或者其它線程等。遇到這個關(guān)鍵字聲明的變量,編譯器對訪問該變量的代碼
就不再進(jìn)行優(yōu)化,從而可以提供對特殊地址的穩(wěn)定訪問。
1、重點(diǎn)是:多看,多寫,多練,多思考。
2、單片機(jī)有很多種,每種的側(cè)重都有不同,在自己想深入的單片機(jī)方向選擇一本經(jīng)典教材,然后將心沉入教材,開始用功學(xué)習(xí)。切記不要只看書,要讀懂書中例子程序,且動手編程實(shí)現(xiàn)它。
3、學(xué)習(xí)編程語言最好的方法是讀程序,讀程序是學(xué)習(xí)C語言入門最快,也是最好的方法。我們大家都應(yīng)該有個體驗。讀了之后就要寫,這一點(diǎn)來不得半點(diǎn)懶惰。如果你C語言功底扎實(shí),按照選定教材鉆研幾天便可上手開發(fā)單片機(jī)軟件。
#include stdlib.h
srand(dat); //初始化隨機(jī)種子,使用該函數(shù)需要上面的頭文件。如果不要這個,每次開機(jī),對應(yīng)的隨機(jī)數(shù)都是相同的. dat 也是需要是個隨機(jī)數(shù),一般可以用掉電存儲的方式來讀取。
dat = rand() ;
延時時間的計算與單片機(jī)的晶振頻率有關(guān)。若晶振頻率為12Mhz,那么單片機(jī)每震動一次所需要的時間是1/12M s。那么再來看看單片機(jī)執(zhí)行一次自減所需要的振動次數(shù)是96次,假如我們對時間要求不是特別精確的話,可以約等于100來計算。現(xiàn)在通過上面兩個數(shù)據(jù)可以得出:單片機(jī)每執(zhí)行一次自減所需要的時間是1/12M *100(s),即1/120000 s,逆向計算一下,每1ms需要自減多少次?120次對吧。所以一個簡單的延時功能就誕生了,我們只需要自減120次,就可以延時1ms,如果我們要延時50ms呢,那就自減50*120=6000次。那么在程序上如何表達(dá)呢?我們可以用兩套for循環(huán)
void delay(int i){
int x,y;
for(x=i;x0;x--){
for(y=120;y0;y--)
}
}
參數(shù) i 代表該函數(shù)延時多少ms
分享文章:單片機(jī)如何寫好c語言函數(shù) 單片機(jī)c語言函數(shù)大全
網(wǎng)站網(wǎng)址:http://chinadenli.net/article28/dodjjjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、品牌網(wǎng)站制作、網(wǎng)站制作、網(wǎng)站排名、、全網(wǎng)營銷推廣
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)