I.STM32 DWT时间戳功能实现
4 r& z3 U& @4 l 1.m3、m4实测可用。) S/ X* g( G3 ~
2.精度:1/内核频率(s)。
* s6 X8 W1 ~3 _ V 3.实现流程:
4 X4 K: w F( j3 d: A4 C* T a.先使能DWT外设,由内核调试寄存器DEM_CR的位24控制,写1使能。5 M- ^: Z9 |' }$ E9 Y! F
b.使能CYCCNT寄存器之前,先清0。
4 D' W+ S. S8 Q( `$ b c.使能CYCCNT寄存器,由DWT_CTRL的位0控制,写1使能。
0 @, p( _6 y1 M6 Z, u5 j8 V 4.实现代码如下: - 1 //寄存器基地址
4 e8 r0 _6 T: ^ - 2 #define DWT_CR *(uint32_t*)0xE00010008 T: s. j" V$ R1 @+ S1 P
- 3 #define DWT_CYCCNT *(uint32_t*)0xE0001004
& g" X8 ^% y" i3 M - 4 #define DEM_CR *(uint32_t*)0xE000EDFC4 O" ]8 f+ a( H4 t
- 5 3 [# `3 {: n/ q" o- u
- 6 //定义需使能位' q7 G4 Y, w7 r) q8 n- O+ i
- 7 #define DEM_CR_TRCENA (1<<24)
) k$ o( w; F. Q - 8 #define DWT_CR_CYCCNTENA (1<<0), K# C& I# r7 E0 P* U
- 9 ) ]/ X8 P; h7 Q
- 10 //DWT init" T0 c6 j& K) s9 ]4 @
- 11 void DWT_init(void)4 J$ m. }( ]/ T/ U# r- o9 Z6 F
- 12 {2 N7 T3 H* L0 X1 Z* ~- \
- 13 DEM_CR |= (uint32_t)DEM_CR_TRCENA;
2 Y' d( s# k4 d. Y - 14 DWT_CYCCNT = (uint32_t)0u;+ ~% t" q8 S7 H7 }3 S* B
- 15 DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;8 C- \/ b7 i5 _% h
- 16 }
9 Z! |8 ^( u: F( }0 {/ \4 k6 A - 17 //get DWT count
* v0 {9 z: W% w, J) s - 18 uint32_t DWT_TS_GET(void)$ ^6 t, F1 P& W. h$ D( V/ p2 i
- 19 {
' H& G: W( t4 `/ I# C - 20 return((uint32_t)DWT_CYCCNT);
_$ ~9 L+ a { { - 21 }
+ `6 D% e( r, @- x* j c$ x
复制代码 0 Q& Y( c5 z0 A. c
5.使用场景:0 m' {0 C6 ]" t% { W3 `, r
a.可用来实现延时功能。/ K6 }- A$ ]/ P9 }) r
b.测量程序运行时间。 N* m9 W- y \6 M4 T5 n
c.。。。。。 II.STM32 ITM调试功能实现 1.概念:ITM是一应用驱动的跟踪源,它支持printf类的调试手段来跟踪操作系统和应用事件,+ D" I1 X( w; ^& U/ f
并发布判定的系统信息。ITM以包的形式发布跟踪信息。/ c$ q2 n% ~# D7 \7 V4 p
2.实际应用:当调试时需要打印出信息,而又不能占用串口时,ITM就派上用场了。
7 ^$ c/ M2 N; [0 C 3.m3、m4实测可用。" D2 `0 o( Y! N* y! E3 I
4.配置步骤:+ A, ]( O0 \8 [) E+ x2 a
a.配置TPIU并使能I/IO_TRACEN以使能TRACE的引脚8 s2 o3 m7 y5 M8 v; {
b.向Trace Lock Access寄存器写入0xC5ACCE55,以允许写其他ITM寄存器5 w' Q! r4 H: N# I3 k( ?/ S0 r3 y9 m
c.向Trace Control寄存器写入0x00010005,使能TPIU的同步包并使能整个ITM功能,
" N, L3 ]4 f3 O. }% V+ e" u- W 寄存器中的ATB ID为0x01
6 @: b8 a) @ j# D/ R4 [* k4 ? d.向ITM Trace Enable寄存器写入0x01,以使能触发端口0# o( d% k7 k" i7 A( Q0 O2 o8 b" W
e.向ITM Trace Privilege寄存器写入0x01,关闭对触发端口7:0的屏蔽! J4 K! B) n$ B9 I6 u. H- H8 V9 C0 o
f.把需要输出的值写入触发端口0寄存器,这个步骤可以通过软件完成(使用printf功能)+ \- ~( ~$ Z2 f% N2 d! d
5.注意事项:
8 r; s- o+ u4 _; Z a.只能使用SWD方式调试* N, P9 X% M& V/ X
b.需要使用到TRACESWO引脚,正常为PB3
5 J- ^% N$ ]& E* U U3 b 6.代码实现: - 1 int main(void)3 S: ^! f. ~7 D" R, w9 r* p
- 2 {
/ P6 O4 V I, ^% e9 U$ S - 3 int dat = 0;5 b% m4 T4 i% [
- 4 1 j7 q8 ?) _! l+ b3 Q: w1 c
- 5 DBGMCU->CR = 0x27;//使能TRACE的引脚2 T' f; _: ]3 A" H$ ]
- 6 ITM->LAR = 0xC5ACCE55;//允许写其他ITM寄存器
4 H* Q y& L! s) r. [ - 7 ITM->TCR = 0x00010005; //使能TPIU的同步包并使能整个ITM功能
0 P5 X y& }4 P' s! u4 r0 ] - 8 ITM->TER = 0x01;//以使能触发端口0; Y3 X0 \$ R4 R0 u/ P! ]( b
- 9 ITM->TPR = 0x01;//关闭对触发端口7:0的屏蔽7 |& W8 J3 o3 J' x7 o$ ` w
- 10 ITM_RxBuffer = 0x5AA55AA5;//如果不需要scanf功能可屏蔽掉
! \6 u( V, n u! }" N" B$ H - 11
2 Q ?% X7 W* e4 }& w, h" h; K" i - 12 printf("input data");2 o6 E3 u% K G( J/ P( \
- 13 for(;;)
0 {3 _+ q5 u! u - 14 {9 n) m' T, S+ U# H( I- K& r
- 15 scanf("%s",&dat);
: [ {( X, U; e* k3 ?% e% Y( C - 16 if(dat)
+ {9 {' q9 I/ _7 F: R' A5 o- ? - 17 {/ ?( h/ P7 { p" v
- 18 ptintf("your input is %d\n",dat);
2 b. a% H+ j& b+ e- O- C$ O9 E1 B - 19 dat = 0;7 i0 u9 l2 u9 J- E$ j* ~1 A7 x7 e
- 20 }3 b0 }% E- L& }" z5 ]) n. ^9 ]
- 21 }
* F/ M6 d' z% V, ? @+ z' ~ - 22 }5 w8 {" Z0 q" z9 e; V! L
- 23 # ~, q$ R/ \7 J: i3 b, `0 }9 p8 j9 v
- 24 //重定义printf功能9 X7 R1 g& {- c Y' B3 a$ T7 U: ]
- 25 int fputc(int ch,FILE *f) g% u3 B# K& e% A" U6 k7 t
- 26 {
! D8 c7 K% s8 _/ H# o4 b - 27 return ITM_SendChar(ch); R+ V2 O. N& j- I* v. b6 A5 d# \1 p4 d
- 28 }( P9 O3 B; e# n Q* U) f- n
- 29 //重定义scanf功能8 e2 ]% a: p- Q
- 30 int fgetc(FILE *f)' f6 a. `. ~& ]8 s( F2 C: O
- 31 {
- V! w8 [0 k9 f4 n; f - 32 while(ITM_CheckChar() != 1) __NOP();* I4 |) Q" l3 v% ] |# X
- 33 return (ITM_ReceiveChar());3 J# t- Z( d$ A8 @
- 34 }
5 O2 K* m% c7 Q4 B. T+ _ - 35
' j9 n6 _/ }$ [# q0 x
复制代码
8 O9 A$ S; j) a1 A2 b/ b" j, I 7.功能窗口: 可使用以下两种方式查看打印信息:# k( p/ s) _/ i& ]4 Q
a.使用keil debug功能。 ) |9 T8 R4 y8 {+ L
" {' a) o' P5 @$ v0 i2 G! c6 C
|