1 程序调试方式 (1) 使用SEGGER J-Flash(J-Link)下载程序到闪存中运行。 (2) 使用串口ISP 来下载HEX 文件到CPU 中运行。 (3) J-Link + MDK 组合,来在线调试程序(可下载、单步调试)。
; i' n) {" c/ e1 @2 e3 Z
下载:是将具体的文件如.axf或HEX下载到开发板的flash(SRAM)中去,在开发板启动之后就会运行所下载文件。根据运行结果再将修改的程序下至开发板中运行。
) m S6 a* Z0 D2 x7 Y: L- 通过J-Link下载.axf文件时是在J-Link开发板与PC连接好后,通过点击KEIL中的“load”按钮将.axf文件下载到开发板内。
- 通过串口ISP下载HEX文件在C51中常见,如51下载程序到单片机内。
/ m4 E% @& T0 e5 N
' u* Z8 D) i: o" R0 V2 J$ ^/ S9 @) j; v# j0 n
( b- \3 }) Z+ V) E" G6 G+ J' [
在线调试:通过调试器(如J-Link)将开发板和PC相连,既将程序下载到开发板中运行又能看见程序运行的结果(如变量的值)。
& M8 G6 f0 y A: x/ }0 b# ~
. e" {( W) K- @7 F7 ~2 MDK-RAM-keil + J-Link在线调试(1) J-Link + 开发板连接PC ) r j) J9 ~( U% d$ t/ q
9 N$ M' J. p% V9 ^
Figure1:使用在线调试工具J-Link: B! G8 s- |7 T8 R7 A- s# \1 \
4 K" Q9 G* }7 B1 d( ^' w+ B
6 t. q- b% G: R
. t5 W& W% ?. D
(2) 设置项目编译属性因为是使用J-Link在线调试程序,需要选择J-Link调试工具(建立工程的时候如果设置好了就不用再设置了)。如果J-Link连接开发板的接口为JTAG则PORT要选择”JTAG”。如下图:* U2 t1 {0 ^: f: s1 R) x
" X k$ }5 U! J
7 | y3 n) G; e4 k7 D
0 a* b* ^( `7 ?1 W4 jFigure2:选择J-Link调试器
4 N" \$ ^# I+ e7 _1 X, S # w8 u0 N! s* A, a! I
如果“JTAG Device Chain”处有内容则说明检测到了设备。- B5 c) r( U4 J% I1 A
' V! e. ]0 k o; Z- f7 h0 ? q6 ^1 w# W/ ^2 q
8 d; G7 O6 b) ^% P& w2 p
8 W# \9 d z- h: `" s; w6 s2 A1 p+ O
还需要在Utilities选项中做一些设置:
2 I7 M; n' i5 T$ {/ L
5 r0 { _; [$ ]- C& i) }1 R' Q : _- M% \& n" ^8 G* D
2 g* ^+ b: n! r; h7 G# m% DFigure3:Utilities设置
+ L. w* o9 H+ {/ i# {$ B, u+ E
4 ~% e5 W! t6 r在”settings”中,点击”Add”按钮时选中开发板的控制芯片即可。然后点击OK保存。现在就可以进行在线调试了。
, D5 e+ `+ r. j' t/ G
. s5 P! r. _. w/ ^% d6 N+ ~" h1 v* s/ {* g" l# o+ A
(3) 在线调试[1] 单步调试开始调试/ A7 F2 k2 N& ~! F; X- G
8 n$ H$ C$ M8 E8 R
, G% {' F$ I3 \) _8 A4 J& k1 t4 Q9 s! a: R; z9 O/ ~; e a
程序经1编译通过后(第一个按钮表示只编译当前处在编辑界面的文件,第二个按钮表示编译整个工程中修改过或还未编译过的文件,最后一个按钮表示重新编译所有的文件)。确认J-Link连接完好,开发板已上电后,点击2中的按钮开始/结束在线调试。
( ~ b% i# _7 {; o! y1 \, u7 w% j3 w$ V0 j9 H

9 X7 [# p! F6 F+ M# M
7 a1 `- ~$ D* y$ [# c$ ~Figure4:在线调试开始
# f+ l; x# G: o3 U/ l a6 k
9 A" E4 t$ R/ _+ f: |; f1 C1:绿色图标表示光标所在的行,黄色图标处为要运行的下一条语句。在线调试开始时处在mian()入口处。
) q( B6 r, ^+ P; B2:这是调试开始后弹出的窗口,watch窗口用来观察程序中各种变量的“值”及“类型”,可以在watch窗口中手动添加待观察变量。* k0 w b+ s, a0 W& m
3:程序中的tx_data为具11个元素的数组,从值可以看出来程序还未运行到175行处。: T4 A- ]% M" z4 {7 X
" ~9 `; P9 b5 K( Y! [) S7 @
3 z# x! o2 L. y2 R+ |
' Q4 o1 x) r2 p, k( q) B) Q单步调试按钮单步模式下可以点击以下图标让程序往下执行:. ]' s, `. ? p8 P: ?7 a) F
( y3 E t" D1 t( J " M0 S) E. t" K& Z$ U
9 j& W, @; [/ Q3 p: b& Y* ^( x* ]以上几个图标对应的快捷键依次是:
2 t) f% m' D/ x6 C# N" |7 k s1 r- F11: 单步执行,每次执行一行。
- F10: 跳过当前行语句。
- Ctrl + F11: 跳出当前函数。
- Ctrl+ F10: 运行到光标所处的行。
( x! e; ^. u# x; F' A" r+ c7 d
8 F! c# H i" D' l7 k4 a8 a
" M3 U) a6 r; q% g" p6 c
按F11到176行时,经执行过得tx_data数组个元素的值就在watch窗口中显示出来。
@* a7 ]) A' U; t9 {' w$ P7 U9 I: ^& q$ |
8 S1 ~7 M4 _7 ^0 W
工具栏窗口在“在线调试”状态下,许多“工具栏小窗口”会冒出来。1 t5 C3 [. t( E4 d
% ]2 t; L- V5 v0 R: z
在红色方框内的几个小窗口从左到右依次是:
5 i$ n" |9 Q, s2 a( A i$ t- Register Window: 用于显示各寄存器的值,并显示运行时间。
- Call Stack Window: 用于显示main函数内的变量及所调用的子函数地址/值。
- Watch Window: 用来查看特殊变量的窗口。用户可自行输入某个变量名,根据程序运行的进度查看其值。0 W/ A- j5 }8 w+ B
其它的窗口也有其特殊的用途,在对其有需要时可以打开瞧瞧。打开和关闭这些窗口的方式都是点击一下图标的方式。
8 ~. D- L- C0 X, Q
! L) @# n4 ~0 P0 B) w. u; e. H1 j% F! m5 a& \& K) [! [
查看寄存器值- 进入调试之后,点击"Peripherals",然后选择要查看的寄存器名称。
- 进入调试之后,点击"View->SystemVier",然后选择要查看的寄存器名称。
- 进入调试之后,点击"View->Watch Windows"或者点击工具栏,只输入指针所指的寄存器的名称。
( n7 ^! |. w `) a9 t7 S$ t
3 ~* ^) ]5 Y( j j9 v" Y9 ?. X) [
* ]) P+ \$ X% V O+ r[2] 设置断点调试单步调试毕竟是单步或者跳过函数的执行。在程序十分庞大时,F系列的键或者鼠标都要被按坏,设置断点后,程序运行到断点处就停下了,然后就可以再用单步调试的方式进行调试。
1 Y6 ~+ |6 l8 B; ?# U
n4 X% q# j B3 F( ^+ ?! w3 M1 }$ n. h9 ]. N, j" x' k
开始在线调试点击调试按钮开始调试,如图Figure 5。
* @4 f& a" C' t& ^: r- A$ Q' X8 D6 j2 _4 O$ H. y
断点设置到想要运行的代码处设置一个断点。设置断点的方法:- t" h# Y* R, ^
- 在源代码行号前双击。
- 用开始/停止在线调试旁边的图标。
- Debug >> Insert/Remove Breakpoint(F9)。
/ o7 g2 O8 D; L* V: G1 k, A( l 8 [1 K) E& d) w% \) ?; [1 J
使能/消除使能/移除断点的方法也是以上列举的3点。
) j7 ?- |9 ?2 I. ?/ i& l8 V( p. D) _0 @ Z( j. ?) P
8 {5 J" j: u% j8 ]: |点击Run - Debug>> Run(F5)
; U6 p1 n* V' T6 ^, v+ {% n
经以上3个步骤后,代码就从上一次代码停留处运行到断点处,结合Figure 4看下图。# n/ h; e. K$ M% `. [
1 h, a# m" g+ h* e; T
) x0 N2 f* r) Z* p6 O, M 2 g, U4 p- j: _& [3 h: L- Z
& o2 H* Y7 M" H5 g& x
Figure6:断点处$ t T! W5 X2 y H: r+ o
9 E2 o/ w2 N1 h
) v' P. H; z/ c0 o3 C基本数据类型占内存大小查看将以下变量声明为全局变量后,在Watch窗口中观察的各变量的值。
1 d. P. |4 C! k( P9 ?0 O# C8 F/ d+ ?2 W: R9 z1 x
cl =sizeof(char);) X6 A4 p" C& J1 i
ucl = sizeof(unsigned char);
: m- g3 J9 }9 s3 | scl = sizeof(signed char);1 ?( K% g9 H+ O7 k( u6 W) A
! h' p. F/ v9 p2 h7 ` il = sizeof(int);
4 f! |1 E* D% A N8 X! ^. j ui = sizeof(unsigned int);
* Z$ q+ A$ e( i sil = sizeof(signed int);0 C; s& a) ?: X- [$ ?1 n' O
w+ v2 c: q, {+ Z- E5 l; D+ r
ll = sizeof(long);
9 {( T' p4 o2 x: L+ {3 d5 y ul = sizeof(unsigned long);6 d1 Z0 b# V6 l7 I9 a' H4 k
sl = sizeof(signed long);* U6 M4 a( e; ~* h" z, _" S+ g s9 o
lll = sizeof(long long);
$ L" F, N& q1 u2 N
+ ?- ?8 W9 J& P& s% S fl = sizeof(float);
2 u5 V- _8 A) }/ [% N2 E
3 g, ~+ v0 X" [( u2 ]; h dl = sizeof(double);( p6 | C! u( L7 e
ldl =sizeof(long double); |
3 x" _$ M6 l' y) b- @: l/ t9 p( n. z+ c
Watch窗口中各变量的值:
7 _1 N8 y) V/ [4 b8 q0 l, c8 Q7 p4 Z3 A; N. {7 @
+ {; ~; ^$ ^( t& x, g& d ! F4 |+ ^# M- g2 o0 Z/ G- I9 S& d8 @
Figure7:Cortex-M3 C语言基本类型大小
! r- L$ i/ f" j# k t% h + W7 K8 _! j6 X- z! S7 i1 ?. h# i8 `
# w% M# x) u- |4 _
在keil下的编译器+stm32f10xxx芯片下,char占一个字节,int占4个字节,long占4个字节,long long 占8个字节,float占4个字节,double占8个字节, long double 占8个字节。
0 q1 c' i5 E F) u9 I o: ~+ |+ ^( a. r9 Z5 v6 l6 d
6 B) {: Z9 V* i! Q! h% E$ I8 |# E* O* ^- P6 A/ i
|