(玩(wan)電子) 電子技術學習與研(yan)xin)/div>
當前位置︰單片機教程網 >> 基礎教程 >> 瀏覽(lan)文章(zhang)

万人炸金花官网

作者:佚名(ming)   來源:本(ben)站原創(chuang)   點擊數:x  更新(xin)時間︰2020年02月10日(ri)   【字體︰

Keil 的調(diao)試命令(ling)、在線匯(hui)編(bian)與斷xi)閔柚/B>

上一講中我們(men)學習了如何建(jian)立工程、匯(hui)編(bian)、連接工程,並獲(huo)得(de)目標代(dai)碼,但是(shi)做到(dao)這(zhe)一 步僅僅代(dai)表你的源程序沒有語法錯誤,至(zhi)于源程序中存在著(zhou)的其它錯誤,必須通過調(diao)試才能 發現並解(jie)決,事(shi)實上,除了極(ji)簡單的程序以外(wai),絕(jue)大部份的程序都要通過反復(fu)調(diao)試才能得(de)到(dao) 正(zheng)確的結(jie)果(guo),因此,調(diao)試是(shi)軟件開發中重要的一個環節,這(zhe)一講將介(jie)紹(shao)常用的調(diao)試命令(ling)、利 用在線匯(hui)編(bian)、各種(zhong)設置斷xi)憬jin)行程序調(diao)試的方法,並通過實例介(jie)紹(shao)這(zhe)些(xie)方法的使(shi)用。

一、常用調(diao)試命令(ling)
在對工程成功地進(jin)行匯(hui)編(bian)、連接以後,按(an) Ctrl+F5 或者使(shi)用菜單 Debug->Start/Stop Debug Session 即可進(jin)入調(diao)試狀態,Keil 內(na)建(jian)了一個仿真 CPU 用來模擬執(zhi)行程序,該(gai)仿真 CPU 功 能強(qiang)大,可以在沒有硬(ying)件和仿真機的情況下進(jin)行程序的調(diao)試,下面將要學的就是(shi)該(gai)模擬調(diao)試 功能。不過在學習之前必須明(ming)確,模擬畢竟只是(shi)模擬,與真實的硬(ying)件執(zhi)行程序肯(ken)定還是(shi)有區(qu) 別的,其中最明(ming)顯的就是(shi)時序,軟件模擬是(shi)不可能和真實的硬(ying)件具有相同的時序的,具體的 表現就是(shi)程序執(zhi)行的速度(du)和各人(ren)使(shi)用的計(ji)算(suan)機有關,計(ji)算(suan)機性能越好,運行速度(du)越快。

進(jin)入調(diao)試狀態後,界(jie)面與編(bian)緝狀態相比(bi)有明(ming)顯的變化,Debug 菜單項中原來不能用的命 令(ling)現在已可以使(shi)用了,工具欄會多(duo)出(chu)一個用于運行和調(diao)試的工具條,如圖 1 所示,Debug 菜 單上xi)拇蟛糠菝ling)可以在此找到(dao)對應的快捷(jie)按(an)鈕,從左(zuo)到(dao)右依次wen)shi)復(fu)位、運行、暫停、單步、 過程單步、執(zhi)行完當前子程序、運行到(dao)當前行、下一狀態、打開跟蹤、觀察跟蹤、反匯(hui)編(bian)窗 口、觀察窗口、代(dai)碼作用範圍分析、1#串行窗口、內(na)存窗口、性能分析、工具按(an)鈕等命令(ling)。

? 圖 1  調(diao)試工具條
學習程序調(diao)試,必須明(ming) 確兩個重要的概念,即單步執(zhi)行與全(quan)速運行。全(quan)速執(zhi)行 是(shi)指一行程序執(zhi)行完以後緊

接著(zhou)執(zhi)行下一行程序,中間不停止,這(zhe)樣程序執(zhi)行的速度(du)很快,並可以看到(dao)該(gai)段程序執(zhi)行的總(zong)體效果(guo),即最終結(jie)果(guo)正(zheng)確 還是(shi)錯誤,但如果(guo)程序有錯,則難以確認錯誤出(chu)現在哪些(xie)程 序行。單步執(zhi)行是(shi)每次執(zhi)行一行程序,執(zhi)行完該(gai)行程序以後 即停止,等待命令(ling)執(zhi)行下一行程序,此時可以觀察該(gai)行程序 執(zhi)行完以後得(de)到(dao)的結(jie)果(guo),是(shi)否(fu)與我們(men)寫該(gai)行程序所想要得(de)到(dao) 的結(jie)果(guo)相同,借此可以找到(dao)程序中問(wen)題(ti)所在。程序調(diao)試中, 這(zhe)兩種(zhong)運行方式都要用到(dao)。

使(shi)用菜單 STEP 或相應的命令(ling)按(an)鈕或使(shi)用快捷(jie)鍵 F11 可 以單步執(zhi)行程序,使(shi)用菜單 STEP OVER 或功能鍵 F10 可以 以過程單步形wen)街zhi)行命令(ling),所謂過程單步,是(shi)指將匯(hui)編(bian)語言 中的子程序或高級語言中的函數作為(wei)一個語句來全(quan)速執(zhi)行。


圖 2  調(diao)試窗口



按(an)下 F11 鍵,可以看到(dao)源程序窗口的左(zuo)邊出(chu)現zhi)艘桓齷粕se)調(diao)試箭頭,指向源程序的第(di)一行,如圖 2 所示。每按(an)一次 F11,即執(zhi)行該(gai)箭頭所指程序行,然後箭頭指向下一行,當箭頭 指向 LCALL   DELAY 行時,再次按(an)下 F11,會發現,箭頭指向了延時子程序 DELAY 的第(di) 一行。不斷按(an) F11 鍵,即可逐步執(zhi)行延時子程序。

通過單步執(zhi)行程序,可以找出(chu)一些(xie)問(wen)題(ti)的所在,但是(shi)僅依靠單步執(zhi)行來查錯有時是(shi)困難 的,或雖能查出(chu)錯誤但效率很低,為(wei)此必須輔之以其它的方法,如本(ben)例中的延時程序是(shi)通過

將 D2︰ DJNZ    R6,D2 這(zhe)一行程序執(zhi)行六萬多(duo)次來chuang) dao)延時的目的,如果(guo)用按(an) F11 六萬多(duo)

次的方法來執(zhi)行完該(gai)程序行,顯然不合適(shi),為(wei)此,可以采(cai)取以下一些(xie)方法,第(di)一,用鼠標在 子程序的最後一行( ret)點一下,把光(guang)標定位于該(gai)行,然後用菜單 Debug->Run to Cursor line

(執(zhi)行到(dao)光(guang)標所在行),即可全(quan)速執(zhi)行完黃色(se)箭頭與光(guang)標之間的程序行。第(di)二,在進(jin)入該(gai)子

程序後,使(shi)用菜單 Debug->Step Out of Current Function(單步執(zhi)行到(dao)該(gai)函數外(wai)),使(shi)用該(gai)命令(ling) 後,即全(quan)速執(zhi)行完調(diao)試光(guang)標所在的子程序或子函數並指向主程序中的下一行程序(這(zhe)里是(shi) JMP   LOOP 行)。第(di)三種(zhong)方法,在開始(shi)調(diao)試的,按(an) F10 而非 F11,程序也將單步執(zhi)行,不同 的是(shi),執(zhi)行到(dao) lcall            delay 行時,按(an)下 F10 鍵,調(diao)試光(guang)標不進(jin)入子程序的內(na)部,而是(shi)全(quan)速 執(zhi)行完該(gai)子程序,然後直接指向下一行“JMP   LOOP”。靈(ling)活應用這(zhe)幾種(zhong)方法,可以大大提 高查錯的效率。

二、在線匯(hui)編(bian)

?
在進(jin)入 Keil 的調(diao)試環境以後,如果(guo)發現程序有錯,可以直接對源程序進(jin)行修(xiu)改,但是(shi) 要使(shi)修(xiu)改後的代(dai)碼起(qi)作用,必須先(xian)退出(chu)調(diao)試環境,重新(xin)進(jin)行編(bian)譯、連接後再次進(jin)入調(diao)試,如 果(guo)只是(shi)需要對某些(xie)程序行進(jin)行測(ce)試,或僅需對源程序進(jin)行臨(lin)時的修(xiu)改,這(zhe)樣的過程未免有些(xie) 麻煩,為(wei)此 Keil 軟件提供了在線匯(hui)編(bian)的能力,將光(guang)標定位于需要修(xiu)改的程序行上,用菜單 Debug->Inline  Assambly… 即可出(chu)現如

圖 3 的對話框,在 Enter  New 後面的 編(bian)緝框內(na)直接輸入需更改的程序語

句,輸入完後鍵入回(hui)車(che)dao) zi)動指向下 一條語句,可以繼續修(xiu)改,如果(guo)不再 需要修(xiu)改,可以點擊右上角的關閉按(an)鈕關閉窗口。



三、斷xi)閔柚/B>

圖 3  在線匯(hui)編(bian)窗口

程序調(diao)試時,一些(xie)程序行必須滿足一定的條件才能被執(zhi)行到(dao)(如程序中某變量達到(dao)一定

的值、按(an)鍵被按(an)下、串口接收到(dao)數據、有中斷產生等),這(zhe)些(xie)條件往往是(shi)異步發生或難以預 先(xian)設定的,這(zhe)類問(wen)題(ti)使(shi)用單步執(zhi)行的方法是(shi)很難調(diao)試的,這(zhe)時ben)鴕 shi)用到(dao)程序調(diao)試中的另一 種(zhong)非常重要的方法——斷xi)閔柚謾6系(xi)閔柚玫姆椒ㄓ卸duo)種(zhong),常用的是(shi)在某一程序行設置斷xi)悖設置好斷xi)愫罌梢勻quan)速運行程序,一旦執(zhi)行到(dao)該(gai)程序行即停止,可在此觀察有關變量值,以 確定問(wen)題(ti)所在。在程序行設置/移除斷xi)愕姆椒ㄊshi)將光(guang)標定位于需要設置斷xi)愕某絛蛐校 shi) 用菜單 Debug->Insert/Remove BreakPoint 設置或移除斷xi)悖ㄒ部梢雜檬蟊暝詬gai)行雙擊實現同 樣的功能);Debug->Enable/D isable   Breakpoint  是(shi)qiang) 艋蛟萃9guang)標所在行的斷xi)愎δ埽Debug->Disable All Breakpoint 暫停所有斷xi)悖ebug->Kill All BreakPoint 清除所有的斷xi)閔置。這(zhe)些(xie)功能也可以用工具條上xi)目旖jie)按(an)鈕進(jin)行設置。

除了在某程序行設置斷xi)閼zhe)一基本(ben)方法以外(wai),Keil 軟件還提供了多(duo)種(zhong)設置斷xi)愕姆椒 /p>

按(an) Debug->Breakpoints… 即出(chu)現一個對話框,該(gai)對話框用于對斷xi)憬jin)行詳細的設置,如圖 4

所示。

圖 4 中 Expression 後的編(bian)緝框內(na)用于輸入表達式,該(gai)表達式用于確定程序停止運行的條 件,這(zhe)里表達式的定義(yi)功能非常強(qiang)大,涉及到(dao) Keil 內(na)置的一套調(diao)試語法,這(zhe)里不作詳細說 明(ming),僅舉若干實例,希望讀者可以舉一反三。

1) 在 Experssion 中鍵入 a==0xf7,再點擊 Define 即定義(yi)了一個斷xi)悖注意,a 後有兩 個等號,意即相等。該(gai)表達式的含(han)義(yi)是(shi)︰如果(guo) a 的值到(dao)達 0xf7 則停止程序運行。除

使(shi)用相等符號之外(wai),還可以使(shi)用>,>=,<,<=,!=(不等于),&(兩值按(an)位與),&&(兩

值相與)等運算(suan)符號。

2) 在 Experssion 後中鍵入 Delay 再點擊 Define,其含(han)義(yi)是(shi)如果(guo)執(zhi)行標號為(wei) Delay 的行 則中斷。

?
3) 在 Experssion 後中鍵入 Delay,按(an) Count 後的微調(diao)按(an)鈕,將值調(diao)到(dao) 3,其意義(yi)是(shi) 當第(di)三次執(zhi)行到(dao) Delay 時才停止程序運 行。

4) 在  Experssion   後鍵入  Delay ,在                     

Command   後鍵入 printf(“SubRoutine

‘Delay’has  been  Called\n”)主程序每次 調(diao)用 Delay 程序時並不停止運行,但會 在輸出(chu)窗口 Command  頁輸出(chu)一行字 符,即 SubRoutine   ‘Delay’ has   been Called。其中“\n”的用途是(shi)回(hui)車(che)換行, 使(shi)窗口輸出(chu)的字符整齊。

5) 設置斷xi)闈跋xian)在輸出(chu)窗口的 Command

頁中鍵入 DEFINE int I,然後在斷xi)閔/p>

圖 4  斷xi)閔柚枚曰翱br / style="PAGE-BREAK-BEFORE: auto" clear=all>

置時同 4),但是(shi) Command 後鍵入 printf(“SubRoutine  ‘Delay’ has  been  Called  %d times\n”,++I),則主程序每次調(diao)用 Delay 時將會在 Command 窗口輸出(chu)該(gai)字符及被調(diao) 用的次wen) SubRoutine ‘Delay’has been Called 10 times。

對于使(shi)用 C  源程序語言的調(diao)試,表達式中可以直接使(shi)用變量名(ming),但必須要注意,設置

時只能使(shi)用全(quan)局(ju)變量名(ming)和調(diao)試箭頭所指模塊中的局(ju)部變量名(ming)。

四(si)、實例調(diao)試

為(wei)進(jin)行程序的調(diao)試,我們(men)首先(xian)給源程序制造(zao)一個錯誤,將延時子程序的第(di)三行“DJNZ R6,$”後的$改為(wei) D1,然後重新(xin)編(bian)譯,由于程序中並無語法錯誤,所以編(bian)譯時不會有任何出(chu) 錯提示,但由于轉(zhuan)移目的地出(chu)錯,所以子程序將陷入無限循環中。

進(jin)入調(diao)試狀態後,按(an) F10 以過程單步的形wen)街zhi)行程序,當執(zhi)行到(dao) LCALL DELAY 行時,

程序不能繼續往下執(zhi)行,同時發現調(diao)試工具條上xi)Halt  按(an)鈕變成了紅色(se),說de) 絛蛟詿瞬斷xi)?zhi)行著(zhou),而我們(men)預期(qi)這(zhe)一行程序執(zhi)行完後將停止,這(zhe)個結(jie)果(guo)與預期(qi)不同,可以看出(chu)所調(diao) 用的子程序出(chu)了差錯。為(wei)查明(ming)出(chu)錯原因,按(an) Halt 按(an)鈕使(shi)程序停止執(zhi)行,然後按(an) RST 按(an)鈕使(shi) 程序復(fu)位,再次按(an)下 F10 單步執(zhi)行,但在執(zhi)行到(dao) LCALL  DELAY 行時,改按(an) F11 鍵跟蹤到(dao)

子程序內(na)部(如果(guo)按(an)下 F11 鍵沒有反應,請(qing)在源程序窗口中用鼠標點一下),單步執(zhi)行程序,

可以發現在執(zhi)行到(dao)“DJNZ    R6,D1”行時,程序不斷xi)卮誘zhe)一行轉(zhuan)移到(dao)上一行,同時觀察 左(zuo)側的寄存器的值,會發現 R6 的值始(shi)終在 FFH 和 FEH 之間變化,不會減小,而我們(men)的預 期(qi)是(shi) R6 的值不斷減小,減到(dao) 0 後往下執(zhi)行,因此這(zhe)個結(jie)果(guo)與預期(qi)不符,通過這(zhe)樣的觀察, 不難發現問(wen)題(ti)是(shi)因為(wei)標號寫chuang)磯模  治wen)題(ti)即可以修(xiu)改,為(wei)了驗證即將進(jin)行的修(xiu)改是(shi)

否(fu)正(zheng)確,可以先(xian)使(shi)用在線匯(hui)編(bian)功能測(ce)試一下。把光(guang)標定位于程序行

“DJNZ                             R6,D1”,打開

在線匯(hui)編(bian)的對話框,將程序改為(wei)“DJNZ  R7,0EH”,即轉(zhuan)回(hui)本(ben)條指令(ling)所在行繼續執(zhi)行,其中

0EH 是(shi)本(ben)條指令(ling)在程序存儲器中的位置,這(zhe)個值可以通過在線匯(hui)編(bian)窗口看到(dao),如圖 3 所示。 然後關閉窗口,再進(jin)行調(diao)試,發現程序能夠正(zheng)確地執(zhi)行了,這(zhe)說de)饜xiu)改是(shi)正(zheng)確的。注意,這(zhe) 時候的源程序並沒有修(xiu)改,此時應該(gai)退出(chu)調(diao)試程序,將源程序更改過來,並重新(xin)編(bian)譯連接,

以獲(huo)得(de)正(zheng)確的目標代(dai)碼。

万人炸金花官网

万人炸金花官网 | 下一页