第一节 软件说明 Keil提供了包括C编译器、宏汇编、链接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(μVision)将这些部分组合在一起。目前软件对中文的支持不友好,不建议安装网上的一些汉化包之类的。另外建立的工程文件路径也尽量不要存在中文,否则可能会出现一些异常。: Y! F" W( R+ ^, a
& o/ D' z7 j8 S% s; A c
第二节 基本调试方法( ?4 v/ U3 j+ O- q
1,基本调试操作:首先点击"Debug->Start/Stop Debug Session"或下图2位置,进入调试:( V# e/ @( }' ?( W
w2004owomso64016781748.png
* ^" Q& n6 Z0 z# g+ V( j2 s如果前面工程配置里选择了复位调试,则进入调试后,会停在main函数头部:
6 C- T0 r: ?: V$ c. c8 C
erscb5dz1pf64016781848.png
" o1 k9 w1 J' a6 T. q. w! x) @, f2,复位:对程序进行复位操作,根据烧录器不同的复位方式配置会触发不同的复位类型。
8 ^0 k# S5 t `2 {/ p# `4 t* [
hc55q5xx3t164016781948.png
" t8 R) N& [; Y5 M/ I3,全速运行:使当前程序开始正常全速运行,直到程序遇到断点时停止。
% `' Q7 W; _! }$ z/ X
cn1xv33444w64016782049.png
+ e5 d( w/ I' t3 h o. |1 g4,停止运行:当程序全速运行时,点击此按键可停止程序运行,停的是当前点击时的程序运行位置。 " L4 u" N1 r Q; D, I
zl2roaz434v64016782149.png
4 j) D6 X5 \; f7 G/ W5,单步调试:根据当前调试的窗口的语言,执行单条语句。如果遇到函数,则会进入函数内部。如果是在反汇编窗口中,则只执行一条汇编指令。& J6 v) e" u/ ?$ |. W( S
ra5kcporf2264016782249.png
# \/ w5 G3 ~; [( {) G* ^
6,单步跳过调试:如果是在C语言窗口中,则是按单条语句执行,与单步调试不同的是,遇到函数不会进入函数内部,而是直接全速运行函数,并跳到下一条语句。
' a# m( m# x, M7 D6 T
aahv3rzge0u64016782349.png
4 t2 C( o" ?7 M' }
7,单步返回调试:如果是在C语言窗口中,则是直接全速运行当前函数后面所有内容,直到函数返回上一级。
9 v) p9 n; D$ ^9 ]0 a
11pckxlyk4y64016782449.png
V4 B6 h/ N e+ L, Z0 d7 I E8,插入/移除断点:如果当前光标所在行未有断点,则插入断点(前提是当前行可以插入,如果无法插入会显示一个感叹号),在有断点的情况下则是移除断点。插入断点后,当前行前面会有个红圆表示断点位置。也可以通过直接点击红圆位置进行插入/移除断点的操作。另一种断点方式,是通过指令来控制,当然也可以使用Keil提供的界面化操作,设置某个变量读或写时触发断点。不过目前貌似有部分芯片不支持这种操作。注:断点最多只能打7个。 " o$ F+ ~% e/ b4 C# x
0finktn1iaz64016782549.png
* B7 n5 g+ M8 K. y% t5 `9 R7 B
9,使能/禁止断点:开启或禁止当前光标所在行的断点。禁止后红圆变成白圆。
! N; m3 Q+ u9 P
umyfcadj5py64016782649.png
. k/ A, E: L! z: ]# F; Z10,禁止所有断点:禁止当前所有的断点。
* o" @; H6 x8 ^/ C
2qxz3ybanmk64016782749.png
6 B. e) \9 U8 ]# M11,删除所有断点:删除所有断点。
) p- i+ M. A' E. u! q3 Z
3y1gumpds0f64016782849.png
5 p# k( q5 F( }" [. {. d& L
1 @$ ^5 F7 b4 b- @1 v; I
第三节 变量调试方法
4 w0 w% j m) R: c 通过"View->Watch Windows->Watch1、Watch2"可以选择打开Watch窗口:
- z3 @9 |) D1 _1 b1 N/ U
z4tdyvpdwa364016782949.png
. f. |( G4 d+ P" T! F; i& j通过选中一个变量,右键添加入对应的Watch窗口,可以追踪查看当前变量的变化状态。注意,只有全局变量可以全程监视,临时变量只有在进入当前函数中才可监视到其数据,用static关键词修饰的变量无法监视。
( R3 K5 j9 k( t$ [9 @8 \
0umpnvjuwtp64016783049.png
" _! P, O5 y! `8 ~( i; }9 k. K
如果当前变量没有实时更新,则需要点击"View->Periodic Window Update"将其勾选上。
! k7 g' A9 n& P/ g3 \: v6 W1 R+ t
zzgnjjyg0cc64016783149.png
. t2 e/ J! ?7 }8 d9 t% Y K
在"Watch"窗口中,可以查看当前变量名称、值、数据类型,如果当前变量类型为结构体,则可以以对应的结构形式进行展开查看。
1 X) F5 [% d. v. j
3mrvhkmp3af64016783249.png
) R4 N9 e; W. ]2 t
) l4 w4 A; J! c! K第四节 内存调试方法
- P) T% G; j" R0 Z. [) s 通过"View->Memory Windows->Memory1/2/3/4"打开Memory窗口: ' U! u( e1 y) d
tm1t3lizxs464016783349.png
% F: Y9 M/ }4 U' a5 m. F这个图标打开的状态下,再次选中则可关闭:
, {/ Q1 \4 c( Q! B
trhp2begl2b64016783449.png
& R0 u% H$ Y- i( x
在Memory窗口中输入想要查看内存的起始地址,另外右上角的锁可以把当前界面锁定下来。
; y4 X# j# g: _9 S
3p4uxacogsw64016783549.png
- h1 {' k/ d. Z1 M5 j% f
) o# k9 m! t- D' `* J( B第五节 系统调试方法
- A: x3 o0 e* k v% U& _ 通过"View->System Viewer"打开窗口,这个窗口用于查看当前单片机外设及内核寄存器的值,在调试外设底层时经常会使用到。在这个窗口中可以直接修改外设寄存器的值,当然部分只读寄存器是无法修改的,有些则是需要在特定条件下才可以设置生效,具体就得看对应的芯片手册里寄存器的说明了。 # @$ C8 W( K, j3 ^3 T' r
5fucodmpdne64016783650.png
9 R1 p$ Y" ~' x' _* [' M+ G+ s3 j# P+ o0 O. p1 j% C: L
第六节 调度调试方法
# V4 i5 N: P7 O: i7 a 可以在"View->Call Stack Window"打开此窗口:
$ }1 _* l; [. Q2 S% b- x
7 _6 l" d# H3 N( U$ D. V4 A这个窗口用于查看当前程序调度关系,当出现有进入硬件错误异常调试时可以快速定位到是哪里触发的异常。这个窗口是的调度关系是从当前程序堆栈里获取的数据并将其图形化,所以如果当前堆栈数据被破坏,则此窗口也将无法查看调度关系。该窗口里显示的调度关系是从下至上调用的,最上面的表示当前程序所处的函数。展开对应的函数,可以查看各层调用函数跳转之前保存的一些临时变量等信息。
Q2 a# ]' x0 i) H9 J. I% g, M+ A* j5 B4 \7 q) F
第七节 寄存器调试方法7 T# h. b0 F3 l: U: W- [
该窗口可在"View->Registers Window"处打开:
! \5 a3 r. D# c: B% f 1 S2 `8 Y6 ^) O# Y; B/ q) C5 V
这个窗口用于查看当前内核的相关寄存器,如汇编里常说的15个通用寄存器。当然调试中比较常用的是其中的SP、LR、PC三个寄存器。SP为当前栈的地址位置,PC为当前程序地址,LR为函数跳转前的地址,即当前函数返回的地址。 $ I/ k" U! u1 Y! z6 i. }4 t
! I- B5 M8 Q6 M* q' w
另外"Banked"中的MSP为当前程序系统主栈,PSP则为操作系统的任务栈,这两者的区别是,如果使用了操作系统,则当前任务中的所有调度关系使用的是任务栈,而类似中断这种内核的操作使用的是主栈;如果未使用操作系统,则只会使用主栈,不会使用任务栈。通过"Internal"可以查看当前是处在中断还是任务中,Mode为"Thread"表示是在线程/任务中,或者是函数中(非中断),为"Handle"表示是在中断中;Privilege为"Privelege"表示当前处于特权模式。Stack为"PSP"表示当前使用的是任务栈,为"MSP"则表示使用的是主栈。 |