淺談單片機調試方法希望對初學(xué)者有幫助
傅紹兵2011-01-31
本文引用地址:http://dyxdggzs.com/article/201611/318720.htm1.利用I/O
1.1利用LED進(jìn)行可視化管理
這種方法需要有多余的I/O。(如果可能,也可以將實(shí)現次要功能的I/O暫時(shí)借來(lái)一用。)
其電路很簡(jiǎn)單,如圖一所示。I/O設置為輸出方式。
我們可以用下面的宏來(lái)定義LED的操作。
#defineLED_YELLOW_ON()PA6D=0
#defineLED_YELLOW_OFF()PA6D=1
#defineLED_YELLOW_FLASH()PA6D^=1
舉個(gè)例子說(shuō)明它的用法。在低功耗的產(chǎn)品設計中,我們一般采用“睡眠à醒來(lái)工作à睡眠à醒來(lái)工作”的工作模式,其程序結構如下:
while(1)
{
HLT = 1;//進(jìn)入睡眠
nop();
clear_WDT();//清看門(mén)狗
//醒來(lái),處理各種事務(wù)
}
如果我們在程序醒來(lái)時(shí)點(diǎn)亮LED,事務(wù)處理完畢時(shí)熄滅LED,那么我們就能“看見(jiàn)”程序的工作狀態(tài),LED將周期性地閃爍。這就是我們稱(chēng)之為可視化管理的原因。(不記得在哪本書(shū)上看到“可視化管理”這個(gè)概念,我借用一下)
其軟件結構是這樣:
while(1)
{
HLT = 1;//進(jìn)入睡眠
nop();
clear_WDT();//清看門(mén)狗
LED_YELLOW_ON();// debug
//醒來(lái),處理各種事務(wù)
LED_YELLOW_OFF();// debug
}
其實(shí)有些仿真器已經(jīng)提供了這種監視程序睡眠狀態(tài)的方法。如果沒(méi)有提供,就可以用以上方法自行實(shí)現。
它的使用很靈活。比如可以用來(lái)在雙時(shí)鐘系統中監視快時(shí)鐘的打開(kāi)和關(guān)閉情況(慢時(shí)鐘一般總是打開(kāi),因為要用作實(shí)時(shí)時(shí)鐘的時(shí)鐘源,而且慢時(shí)鐘耗電很?。?。你可以在打開(kāi)快時(shí)鐘時(shí)點(diǎn)亮LED,關(guān)閉快時(shí)鐘時(shí)熄滅LED,這樣一來(lái)快時(shí)鐘的打開(kāi)和關(guān)閉就一目了然了。
你也可以在某個(gè)中斷中將LED的狀態(tài)取反(使用LED_YELLOW_FLASH()),用來(lái)監視此中斷的產(chǎn)生是否正常。雖然設置斷點(diǎn)也可以知道中斷是否產(chǎn)生,但會(huì )中斷程序的執行,造成不便。
如果你想知道程序有沒(méi)有執行到某個(gè)地方,你也可以將LED_YELLOW_FLASH()放到該位置。
依次類(lèi)推,你可以用這個(gè)方法觀(guān)察任何你想觀(guān)察的事件。
當然你必須互斥地觀(guān)察不同的事件。就是說(shuō),對于一個(gè)LED,在一次調試中,一般只能觀(guān)察一個(gè)事件,否則你自己也弄不清LED的變化到底是代表發(fā)生哪一事件。
另外,你還可以同時(shí)使用兩個(gè)或者更多不同顏色的LED來(lái)監視不同的事件,前提你有多余的I/O。
不中斷程序的執行,又能看到程序的執行情況,應該說(shuō)是一種很有效的調試程序的方法。相比開(kāi)發(fā)工具所提供的單步、斷點(diǎn)、觀(guān)察變量等調試手段,這可以算是一種有效的補充。
1.2利用示波器測試時(shí)間
利用上面的方法,再加一個(gè)示波器,就可以測量程序執行的時(shí)間了。(你可以自己決定
接不接LED)。
比如,在初始化程序中,在打開(kāi)總中斷之前,寫(xiě)如下代碼:
LED_YELLOW_ON();
nop();
LED_YELLOW_OFF();
使用示波器,在捕獲模式下,你應該能捕獲到一個(gè)脈沖,測試它的寬度,假如為30.5us。以OKI ML610Q431為例,一條nop指令包括1 cycles,1 cycles包括1 system clock。這里system clock等于振蕩周期。(注意,不同的單片機對cycles, system clock的定義是不同的,需要參考各自的用戶(hù)手冊)。
那么我們可以這樣計算振蕩器的頻率:1*1*(1/f)=30.5/1000000.
f=32786Hz
當然,如果示波器測量精度不夠,可以多放幾個(gè)nop指令,計算時(shí)再求平均。如果嫌示波器的捕獲模式太麻煩,還可以采用循環(huán)結構,輸出一串方波。比如:
while(1)
{
LED_YELLOW_ON();
nop();
LED_YELLOW_OFF();
nop();
clear_WDT();//清看門(mén)狗
}
這種方法的使用也很靈活。你可以用來(lái)測試主循環(huán)的執行時(shí)間,調用某個(gè)函數所花的時(shí)間,以及某個(gè)中斷處理的時(shí)間(不包括響應中斷和退出中斷的時(shí)間)等等。
當你發(fā)現某些時(shí)候主循環(huán)的執行時(shí)間特別長(cháng)時(shí),可以采用逐步縮小范圍的方法來(lái)找出到底是哪個(gè)函數花費時(shí)間長(cháng),有沒(méi)有可能將其優(yōu)化。
下面是測試主循環(huán)執行時(shí)間的程序結構。
while(1)
{
HLT = 1;//進(jìn)入睡眠
nop();
clear_WDT();//清看門(mén)狗
LED_YELLOW_ON();// debug
Fun1();
Fun2();
Fun3();
Fun4();
LED_YELLOW_OFF();// debug
}
如果發(fā)現上面的執行時(shí)間異常(比如太長(cháng)),你可以調整測試的位置,如下所示:
while(1)
{
HLT = 1;//進(jìn)入睡眠
nop();
clear_WDT();//清看門(mén)狗
Fun1();
LED_YELLOW_ON();// debug
Fun2();
Fun3();
Fun4();
LED_YELLOW_OFF();// debug
}
這樣,你就可以確定執行時(shí)間過(guò)長(cháng)是不是因為Fun1()引起。如果不是,則繼續調整測試位置,逐個(gè)排除,直到找到真正費時(shí)的函數,對其進(jìn)行分析,看看有沒(méi)有可能優(yōu)化。
當然,我們還可以用兩個(gè)或更多I/O對多個(gè)事件進(jìn)行邏輯分析,觀(guān)察他們的先后順序以及測試其時(shí)間間隔。這種方法也很有用,很靈活。在此不詳述。
2.利用LCD進(jìn)行可視化管理
如果你的產(chǎn)品帶LCD顯示,又沒(méi)有多余的IO可供調試,或者你只是想臨時(shí)的調試某個(gè)
功能,那么你可以臨時(shí)使用LCD上的某個(gè)圖標來(lái)指示某個(gè)事件。當某個(gè)事情發(fā)生時(shí),顯示該圖標,否則清除該圖標。
如果想在程序運行中獲得更復雜、更豐富的信息,可以對不同的事件顯示不同的數值。
3.小結
不中斷程序的執行,又能觀(guān)察程序的執行情況,應該說(shuō)是一種很有效的調試程序的方法。
相比開(kāi)發(fā)工具所提供的單步、斷點(diǎn)、觀(guān)察變量等調試手段,這可以算是一種有效的補充。
實(shí)際上,這些調試方法很像PC應用開(kāi)發(fā)的printf調試手段。它可以在不打斷程序運行
的情況下,借助于I/O,LED,示波器,數碼管或LCD顯示,給出各種各樣的提示信息,幫助我們調試程序。
評論