分享一年的程序調(diào)試經(jīng)驗
首先是軟件的編寫環(huán)境,選擇一個編譯平臺對于編寫代碼效率是至關(guān)重要的,在實際開發(fā)中,基本上使用Source Insight這個軟件上編寫和根改程序代碼,本人現(xiàn)在使用的的是Source Insight3.5,這個軟件功能非常強大,可以幫你快速定位代碼、查看代碼變量使用及各位置調(diào)用情況等信息。顏色管理也非常出色,根據(jù)顏色可以判斷各個信息,比如變量是否定義、是局部變量還是全局變量等,可以說只要你使用過了就決不會再想在KEIL環(huán)境下編寫代碼了,當(dāng)然程序很小有點感覺不出來,而對于程序量較大,且充分使用程序模塊化,就是頭文件的使用,定位程序的速度可以達到想到哪里就定位到哪里。熟悉后基本是使用各個快捷鍵進行操作,到那時KEIL就是當(dāng)作一個編譯器使用了。
KEIL建工程還是很有講究的,假如代碼比較大時,而工程全部又放在同一個文件里,那這個文件里的東西就像雜貨間,找一個東西都難。如下建立一個工程簡單keil工程,這樣建的工程,在keil設(shè)置相關(guān)的頭文件調(diào)用路徑,清單與工程存放文件等設(shè)置后,整個工程的程序代碼就跟keil工程文件獨立了,這樣就對代碼的移植及備份帶來很大的方便,當(dāng)然還有分得更細(xì)的工程了。這樣一來Source Insight工程里添加文件,SVN版本管理代碼就方便了。
變量及函數(shù)的定義在一個工程里命名習(xí)慣是非常重要的,做到看到函數(shù)或變量名就可以知道變量和函數(shù)的意義及作用。我一般命令根據(jù)函數(shù)功能相關(guān)的關(guān)鍵字進行命名,而關(guān)鍵字與關(guān)鍵字之間用大小寫區(qū)分,我英語也很差,但語法可以不懂,但專業(yè)英語的單詞還是要會使用的。而變量定義能用結(jié)構(gòu)體的盡量使用,比如時間就可以構(gòu)建一個時間結(jié)構(gòu)體變量,里面包含年、月、日、時、分、秒、星期,這樣定義了一個時間就非常容易操作而且直觀。
程序的調(diào)試是寫程序最重要的環(huán)節(jié),好的調(diào)試方法可以快速完成程序調(diào)試。以前調(diào)試就是要在板上設(shè)置一盞燈,不然程序跑到哪里出了問題都不知道,所以以前沒燈都不知道怎么樣去調(diào)試,但即使有燈調(diào)試,這樣效率也是很低的而且實際中也不太現(xiàn)實。使用串口打印信息來調(diào)試程序,可以完全跟TUBRO C 2.0下的printf函數(shù)格式進行信息打印,如使用%d,%s、%f、%c打印各類型變量值,而這個功能函數(shù)就是debug.c和debug.h模塊文件,在這里預(yù)編譯發(fā)揮著重要的作用,可以根據(jù)自己配置的定義去控制打印的信息,當(dāng)程序調(diào)試結(jié)束后就關(guān)閉打印信息,這樣編譯器就不會編譯調(diào)試信息,這有就不用一個一個把調(diào)試代碼刪掉了,當(dāng)要更改程序時,可以重新打開編譯信息,這就充分使用了C語言里的預(yù)編譯和DUBUG的使用,這就是為什么程序里存在調(diào)試版和釋放版,而調(diào)試版程序運行時,往往在串口可以看到相關(guān)的信息。斷言(assert (條件))也是檢測程序里關(guān)鍵參數(shù)一個重要調(diào)試方式,但條件不成立時打印出錯所在的文件下的第幾行和錯誤條件信息。串口調(diào)試環(huán)境構(gòu)建當(dāng)使能調(diào)試時要開銷一部分資源,不過現(xiàn)在單片機基本上有外擴RAM,從而使串口調(diào)試在51單片機上調(diào)試成為可能。
附:本人調(diào)試keil51時遇到打印char 類型出現(xiàn)了一些問題,比如char a=0X01,用printf(“a=%c”,a),串口會打印出a=0100, 用printf(“a=%d”,a),串口會打印出a=512,而keilARM里沒出現(xiàn),應(yīng)該是51keil標(biāo)準(zhǔn)庫的問題。
程序的屏蔽,以前最常用的是“ // ”和”/**/”來注釋掉程序,//是屏蔽掉一行的代碼,當(dāng)要屏蔽一段代碼時就會使用/**/來屏蔽,但往往一些注釋也用/**/來注釋,如果在屏蔽段代碼中剛好用/**/的注釋,那是問題就出現(xiàn)了,以前就會把代碼段里/**/該成//注釋?,F(xiàn)在就我們可以使用#if<條件>一段代碼#endif來屏蔽一段代碼,當(dāng)條件為真時編譯器編譯代碼,如為0則不編譯代碼,這樣就容易多了。
前后臺系統(tǒng),寫程序中處理單個任務(wù)在難的功能只算是一個功能,代碼多容易寫,當(dāng)任務(wù)多個給且任務(wù)看似實時的,如數(shù)碼管顯示,按鍵操作、流水燈、點陣顯示燈這樣的任務(wù)放在一起的時候,就存在時間調(diào)配問題。這些我們按鍵按下時要馬上反應(yīng)、數(shù)碼顯示、點陣顯示、流水燈都是要實時處理的,比如按鍵按下不能及時反應(yīng),要麻處理按鍵時顯示停在某個狀態(tài),而這些現(xiàn)象在實際中是完全可以同時出現(xiàn)的,而你是看不的上面的現(xiàn)象,而處理這樣的事件往往是*前后臺系統(tǒng)運行起來的,而前后臺系統(tǒng)就是看定時器來構(gòu)建這個程序的軟中斷一樣,比如單片機里的中斷就是一個機器周期去查詢中斷的狀態(tài)位,如符合中斷,程序就會放下當(dāng)前代碼去執(zhí)行中斷代碼,但按鍵、數(shù)碼顯示、點陣這些對人來說是時間很短的,但對于單片機來說是很長的,有了這樣的思維后我們就可以構(gòu)建一個由我們自己定的模擬軟件中斷查詢周期,這個周期就是*定時器來設(shè)置中斷間隔時間,而這個在定時器里處理的事件最好是占用時間短,比如計數(shù)、少數(shù)個賦值、狀態(tài)判斷及標(biāo)記,然后后臺(main()函數(shù)里的代碼)就根據(jù)前臺(TimerTnterrupt()函數(shù)里的代碼)返回的標(biāo)記狀態(tài)進行處理相應(yīng)事件。這就有點像操作系統(tǒng)的系統(tǒng)節(jié)拍,簡稱為系統(tǒng)的心臟。
評論