for(;;){ mDelay(10); // 延時 10
毫秒
i++;
if(i==10)
{ P1_0=!P1_0; i=0; mDelay1(10);}
} }
編譯連接。進入調試狀態(tài)后使用菜單 View->Performance Analyzer Window,打開性能分 析對話框,進入該對話框后,只有一項 unspecified,點鼠標右鍵,在快捷菜單中選擇 Setup PA 即打開性能分析設置對話框,對于 C 語言程序,該對話框右側的“Function Symbol”下的 列表框給出函數符號,雙擊某一符號,該符號即出現在 Define Performance Analyzer 下的編 緝框中,每輸入一個符號名字,點擊 Define 按鈕,即將該函數加入其上的分析列表框。對 于匯編語言源程序,Function Symbol 下的列表框中不會出現子程序名,可以直接在編緝框 中輸入子程序名,點擊 Close 關閉窗口,回到性能分析窗口,此時窗口共有 4 個選項。全速 執(zhí)行程序,可以看到 mDelay 和 mDelay1 后出現一個藍色指示條,配合上面的標尺可以直觀 地看出每個函數占整個執(zhí)行時間的比例,點擊相應的函數名,可以在該窗口的狀態(tài)欄看到更 詳細的數據,其中各項的含義如下:
Min:該段程序執(zhí)行所需的最短時間;Max:該段程序執(zhí)行所需的最長時間;Avg:該 段程序執(zhí)行所花平均時間;Total:該段程序到目前為目總共執(zhí)行的時間;%:占整個執(zhí)行時 間的百分比;count:被調用的次數。
本程序中,函數 mDelay 和 mDelay1 每次被調用都花費同樣的時間,看不出 Min、Max、
和 Avg 的意義,實際上,由于條件的變化,某些函數執(zhí)行的時間不一定是一個固定的值, 借助于這些信息,可以對程序有更詳細的了解。下面將 mDelay1 函數略作修改作一演示。
void mDelay1(unsigned char DelayTime)
{ static unsigned char k;
unsigned int j=0;
for(;DelayTime>0;DelayTime--)
{ for(;j {;} } k++; } 程序中定義了一個靜態(tài)變量 K,每次調用該變量加 1,而 j 的循環(huán)條件與 k 的大小有關,
這使每次執(zhí)行該程序所花的時間不一樣。編譯、執(zhí)行該程序,再次觀察性能分析窗口,可以
看出 Min、Max、Avg 的意義。
3、變量來源瀏覽
該窗口用于觀察程序中變量名的有關信息,如該變量名在那一個函數中被定義、在哪里 被調用,共出現多少次等。在 Source Browse 窗口中提供了完善的管理方法,如過濾器可以 分門別類地列出各種類別的變量名,可以對這些變量按 Class(組)、Type(類型)、Space
(所在空間)、Use(調用次數)排序,點擊變量名,可以在窗口的右側看到該變量名的更 詳細的信息。
4、代碼作用范圍分析
在你寫的程序中,有些代碼可能永遠不會被執(zhí)行到(這是無效的代碼),也有一些代碼 必須在滿足一定條件后才能被執(zhí)行到,借助于代碼范圍分析工具,可以快速地了解代碼的執(zhí) 行情況。
進入調試后,全速運行,然后按停止按鈕,停下來后,可以看到在源程序的左列有三種 顏色,灰、淡灰和綠,其中淡灰所指的行并不是可執(zhí)行代碼,如變量或函數定義、注釋行等 等,而灰色行是可執(zhí)行但從未執(zhí)行過的代碼,而綠色則是已執(zhí)行過的程序行。使用調試工具 條上的 Code Coverage Window 可打開代碼作用范圍分析的對話框,里面有各個模塊代碼執(zhí) 行情況的更詳細的分析。如果你發(fā)現全速運行后有一些未被執(zhí)行到的代碼,那么就要仔細分 析,這些代碼究竟是無效的代碼還是因為條件沒有滿足而沒有被執(zhí)行到。
二、部份高級調試技巧
Keil 內置了一套調試語言,很多高級調試技巧與此有關,但是全面學習這套語言并不現 實,這不是這么幾期連載可以勝任的,這里僅介紹部份較為實用的功能,如要獲得更詳細的 信息,請參考 Keil 自帶的幫助文件 GS51.PDF。
1、串行窗口與實際硬件相連
Keil 的串行窗口除可以模擬串行口的輸入和輸出功能外還可以與 PC 機上實際的串口相 連,接受串口輸入的內容,并將輸出送到串口。這需要在 Keil 中進行設置。方法是首先在 輸出窗口的 Command 頁用 MODE 命令設置串口的工作方式,然后用 ASSIGN 命令將串行 窗口與實際的串口相關聯(lián),下面我們通過一個實例來說明如何操作。例 6:
ORG 0000H JMP START
ORG 3+4*8 ;串行中斷入口
JMP SER_INT START:
MOV SP,#5FH ;堆棧初始化
CALL SER_INIT ;串行口初始化 A SETB EA ;
SETB ES ;
JMP $ ;主程序到此結束
SER_INT:
JBC RI,NEXT ; 如果串口接收到字 符,轉
評論