I.STM32 DWT时间戳功能实现
9 Q+ _$ \' c. c } 1.m3、m4实测可用。
. W/ z% R) H- d& ^) S, N 2.精度:1/内核频率(s)。 U; T9 h) F4 S( N! d* s V
3.实现流程:" C. M: x. w$ e, @) D9 W: P
a.先使能DWT外设,由内核调试寄存器DEM_CR的位24控制,写1使能。4 V& ?: o% M/ D- s7 U
b.使能CYCCNT寄存器之前,先清0。
; S3 M% q4 [/ o- J. K: }) e& Q c.使能CYCCNT寄存器,由DWT_CTRL的位0控制,写1使能。. D( C: B4 @0 D5 R2 ]$ M
4.实现代码如下: - 1 //寄存器基地址
+ O; H* ]3 z" y& a - 2 #define DWT_CR *(uint32_t*)0xE00010000 w+ j/ x! M* w- E" i% m
- 3 #define DWT_CYCCNT *(uint32_t*)0xE0001004
$ S; x. W& G8 U1 E7 h m - 4 #define DEM_CR *(uint32_t*)0xE000EDFC9 U' ^+ v7 {/ C0 H
- 5
, j5 Q( C/ B( i, x1 L1 @) J - 6 //定义需使能位
* O: K9 I& q8 A+ N4 W) Q( G/ F - 7 #define DEM_CR_TRCENA (1<<24)
4 U) s# z! u7 D4 G; q - 8 #define DWT_CR_CYCCNTENA (1<<0)
( A* o5 p0 w2 C3 w7 D! v2 B1 a - 9
* M9 |8 L$ r8 z- L - 10 //DWT init
1 D, g4 ~7 k: y5 [1 l1 F- V - 11 void DWT_init(void)* n) B9 N, {7 O: d
- 12 {
T# p* k- @) u3 W - 13 DEM_CR |= (uint32_t)DEM_CR_TRCENA;
% f# n: g- c3 {5 \( R4 x4 g' H - 14 DWT_CYCCNT = (uint32_t)0u;
/ [$ u( l) G& w$ X - 15 DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;8 t; ^0 i) G5 g
- 16 }
U1 b( s3 H4 ]% o$ x - 17 //get DWT count( k, i' |# L3 r, ~5 |9 W
- 18 uint32_t DWT_TS_GET(void)# d/ H2 A: L. Y" Z; i, m0 U7 Q
- 19 {- t2 V. l# t2 C$ \8 K
- 20 return((uint32_t)DWT_CYCCNT);
2 G9 X J1 z' ] - 21 }
6 y0 }- a6 A8 M" e# P# }( D# P
复制代码
4 L5 \' l! \$ f7 p1 d, S2 x 5.使用场景:1 F) l3 f+ J/ K: r! F/ D5 T* z0 l* q
a.可用来实现延时功能。/ t' K" O* |8 d; M, _
b.测量程序运行时间。& N1 n# t2 K/ _! D# i' a* f' k3 ]8 f. X
c.。。。。。 II.STM32 ITM调试功能实现 1.概念:ITM是一应用驱动的跟踪源,它支持printf类的调试手段来跟踪操作系统和应用事件,
1 k6 z. Q0 |: ]. C 并发布判定的系统信息。ITM以包的形式发布跟踪信息。
, O$ K9 ~ r9 \ 2.实际应用:当调试时需要打印出信息,而又不能占用串口时,ITM就派上用场了。0 P, H; U/ K4 L; ?
3.m3、m4实测可用。
4 B6 `4 v5 a" e1 z8 l1 {* y 4.配置步骤:
( x4 z/ ^5 f" K1 W6 q3 o4 [ a.配置TPIU并使能I/IO_TRACEN以使能TRACE的引脚
- C4 J! K7 k6 J+ P; P4 b b.向Trace Lock Access寄存器写入0xC5ACCE55,以允许写其他ITM寄存器' V" O D/ ?6 R" `
c.向Trace Control寄存器写入0x00010005,使能TPIU的同步包并使能整个ITM功能,
' H$ ]* }+ \6 I0 w" ?( ^! h: z J 寄存器中的ATB ID为0x01, }! ~! `1 y( y3 r
d.向ITM Trace Enable寄存器写入0x01,以使能触发端口08 j4 f' ^% e& `5 _/ y1 ]$ c! d1 ?* |
e.向ITM Trace Privilege寄存器写入0x01,关闭对触发端口7:0的屏蔽; x" W, v8 z! k$ j! `
f.把需要输出的值写入触发端口0寄存器,这个步骤可以通过软件完成(使用printf功能); r: ]' T6 z: R3 G- Z6 c6 v' w
5.注意事项:
) T3 F! l# d# l" [$ i* j a.只能使用SWD方式调试
" j6 a9 W% ~, L j# ? l* W j b.需要使用到TRACESWO引脚,正常为PB33 A0 W# j9 b |2 q
6.代码实现: - 1 int main(void)9 U K" h7 y6 I5 p1 P
- 2 {) t" J/ V$ a" n; k U% w4 G6 s- D
- 3 int dat = 0;; k% L# k& w) [: N; E7 @" W
- 4
0 G/ y/ `7 F, A0 ?; U$ D" v! ] - 5 DBGMCU->CR = 0x27;//使能TRACE的引脚$ B1 Z7 q4 m) P( i& W
- 6 ITM->LAR = 0xC5ACCE55;//允许写其他ITM寄存器
5 |8 b! @0 R* k2 v6 P6 B: X- H - 7 ITM->TCR = 0x00010005; //使能TPIU的同步包并使能整个ITM功能! ]' v y6 I+ q/ Q1 s5 X3 B4 {/ f
- 8 ITM->TER = 0x01;//以使能触发端口0
( h# _9 V: Q" _+ H - 9 ITM->TPR = 0x01;//关闭对触发端口7:0的屏蔽 b o1 C1 m$ Q5 P( v- K3 G5 ?
- 10 ITM_RxBuffer = 0x5AA55AA5;//如果不需要scanf功能可屏蔽掉0 z$ Y; ?1 t* X# N) {& K- x
- 11 & I$ Q: `1 K3 S
- 12 printf("input data");
# {5 j% ~8 u, x- p - 13 for(;;)( P& l6 ?* n- J1 Z* u
- 14 {( i+ w( o+ B w
- 15 scanf("%s",&dat);) [4 Q2 L9 o# b: {9 S; N6 \( A
- 16 if(dat)
- ]) W; Z5 a+ t - 17 {1 U2 Z$ [5 Y1 t! R1 U; s7 Y
- 18 ptintf("your input is %d\n",dat);
) D2 \: K, }8 V0 F# Q/ a% ~) [; y - 19 dat = 0;
! U3 k2 q' B' O0 \$ ^* \ - 20 }
% \9 |# F5 G5 B9 i. S! r6 H - 21 }% x( B2 U; R8 L; L! N
- 22 }9 i; g6 [) ]' x
- 23
* K. r2 `5 B: G: A/ f; X - 24 //重定义printf功能, q# _- B- q2 W; ^8 @. U% P0 d
- 25 int fputc(int ch,FILE *f). n5 S( k+ J+ @3 T4 I8 f8 Y6 J
- 26 {
" y9 g+ I/ D% r( t# P/ D/ L - 27 return ITM_SendChar(ch);
6 X$ Q9 E( ]2 I5 G7 Y - 28 }
* H8 j7 q- ~: ]6 _6 T - 29 //重定义scanf功能
1 @7 z. D$ K- I; H. ?& y - 30 int fgetc(FILE *f)) w- Z5 r) I9 X F' h! D. v
- 31 {
1 C) Z1 z# n, L" m! u+ N - 32 while(ITM_CheckChar() != 1) __NOP();
3 W( V6 M! z8 j7 J9 u( O7 u& c4 e - 33 return (ITM_ReceiveChar());
# T/ g# S8 F! T% s3 ]+ N; Q' i - 34 }
( h4 ^3 e0 M: Y - 35 / K8 b# q2 D: }7 {1 N7 j9 Q- b
复制代码
! h) s2 F/ Z. Q: s8 e1 H 7.功能窗口: 可使用以下两种方式查看打印信息:' _# h: ?5 D$ n: L& r& `( W Q
a.使用keil debug功能。 & H2 b/ w$ O0 l2 I
+ {3 q6 ~; o4 M+ l" o1 B
|