|
I.STM32 DWT时间戳功能实现% p) c1 C& @7 _+ \9 ^+ X
1.m3、m4实测可用。" Y. r5 B, l* }* s
2.精度:1/内核频率(s)。
( A! B$ j* R4 E) @2 J! c. A U, J$ p 3.实现流程:
- [* L* m, n7 a: ?4 f1 e a.先使能DWT外设,由内核调试寄存器DEM_CR的位24控制,写1使能。0 w+ P! m& _4 j$ M; d9 V. T
b.使能CYCCNT寄存器之前,先清0。. G; W8 O0 @6 J( X3 S' ]. B, ]
c.使能CYCCNT寄存器,由DWT_CTRL的位0控制,写1使能。
! ?; D7 a7 `+ k; z5 ?: N C 4.实现代码如下: - 1 //寄存器基地址
" x4 N6 e$ d( V8 X% ~) R+ K - 2 #define DWT_CR *(uint32_t*)0xE0001000; Q$ T- m" J& J
- 3 #define DWT_CYCCNT *(uint32_t*)0xE0001004
1 E; S4 U X7 w/ d* B0 Z& N5 c - 4 #define DEM_CR *(uint32_t*)0xE000EDFC
% p2 U: T- r( P; Y' Z - 5 : J- C0 s+ _# p6 X4 T
- 6 //定义需使能位
6 ?6 N5 Q/ R. s( g7 d - 7 #define DEM_CR_TRCENA (1<<24)8 v2 D2 K S2 P: N* _) ~
- 8 #define DWT_CR_CYCCNTENA (1<<0); w: _( j/ l/ ^" E7 g
- 9
& g& v& L( ^" [0 r - 10 //DWT init
. O( v& X3 U% E - 11 void DWT_init(void). S5 M2 l- I4 t0 z+ g- e
- 12 {* a' L; H5 A% H2 n! F
- 13 DEM_CR |= (uint32_t)DEM_CR_TRCENA;
) J/ H+ a' a/ N& ^+ G7 |% d - 14 DWT_CYCCNT = (uint32_t)0u;/ c7 p1 ^) N/ t. y( M
- 15 DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;; Z5 C9 J5 |% x1 _1 q: B2 F$ T- i
- 16 }: p0 R6 V/ ~$ z4 K- x
- 17 //get DWT count
) y2 I8 l' c( o - 18 uint32_t DWT_TS_GET(void)$ V- ?) y2 j/ p6 i
- 19 {6 a9 f& Z- P% @; J" `9 |# p
- 20 return((uint32_t)DWT_CYCCNT);
e% t6 G) ?# @0 t6 ~2 P3 } - 21 }
. q" `$ ^6 j+ ]# z5 @9 T" ~
复制代码 8 N! e# j* Q4 e- v
5.使用场景:; S% ~$ l" i' w% C, y. P8 n( v& [; v
a.可用来实现延时功能。
( r! f! I' f: L8 Q8 R5 B G! R% {1 z3 C b.测量程序运行时间。
# K& ]% D) t% w5 s5 U' W, _. O c.。。。。。 II.STM32 ITM调试功能实现 1.概念:ITM是一应用驱动的跟踪源,它支持printf类的调试手段来跟踪操作系统和应用事件,
8 H/ @* T8 ?, `) ^" {7 L 并发布判定的系统信息。ITM以包的形式发布跟踪信息。0 ^7 ]8 E) m5 j" s! u
2.实际应用:当调试时需要打印出信息,而又不能占用串口时,ITM就派上用场了。( f2 p' i- [& C
3.m3、m4实测可用。
, C/ X5 h1 D9 X3 q% S9 f C 4.配置步骤:( p g0 R% z% l3 |, `7 X
a.配置TPIU并使能I/IO_TRACEN以使能TRACE的引脚
8 o( Q6 M2 @9 v3 C/ K1 e b.向Trace Lock Access寄存器写入0xC5ACCE55,以允许写其他ITM寄存器8 T& k9 d& l/ ?' B& o: Z
c.向Trace Control寄存器写入0x00010005,使能TPIU的同步包并使能整个ITM功能,
5 b L! s3 R; R5 ]6 b$ c9 h 寄存器中的ATB ID为0x01
3 c# ?( | Q; h d.向ITM Trace Enable寄存器写入0x01,以使能触发端口0
( @. E& I, y; G: J e.向ITM Trace Privilege寄存器写入0x01,关闭对触发端口7:0的屏蔽
+ \+ Z8 X, D; n2 x+ | f.把需要输出的值写入触发端口0寄存器,这个步骤可以通过软件完成(使用printf功能)
4 G6 @) r$ f0 r4 j3 L 5.注意事项:
4 D+ y/ v! S) L% ~ a.只能使用SWD方式调试6 ?# O$ \8 A# y4 ]0 r2 w I
b.需要使用到TRACESWO引脚,正常为PB3
& }- l5 a1 C+ m4 B8 z% i 6.代码实现: - 1 int main(void)) W) Z% ^3 h7 @- D2 i# @$ R! C( S
- 2 {
# m% T7 F) `7 y" U! C - 3 int dat = 0;6 M) l c- o6 r6 f- w8 s7 g
- 4 7 o' r) i7 _' S; M0 z5 f( p0 V
- 5 DBGMCU->CR = 0x27;//使能TRACE的引脚9 o1 |) H' W4 C. U! |
- 6 ITM->LAR = 0xC5ACCE55;//允许写其他ITM寄存器
, E+ t- S& M5 x3 z4 }( N g - 7 ITM->TCR = 0x00010005; //使能TPIU的同步包并使能整个ITM功能! F; d+ \8 S+ e2 q
- 8 ITM->TER = 0x01;//以使能触发端口0
8 I" Q8 Q( ~2 q7 R$ Q$ X( Z3 C$ f% @ - 9 ITM->TPR = 0x01;//关闭对触发端口7:0的屏蔽
5 y( k7 b! Q: Y z+ Z6 {* U0 i - 10 ITM_RxBuffer = 0x5AA55AA5;//如果不需要scanf功能可屏蔽掉
0 f6 |, S8 H2 D2 `/ F - 11
) C# m" Z5 M( c2 n5 i0 r% y! W! T - 12 printf("input data");
7 |( d7 Z1 C/ T" p; j - 13 for(;;)
. S+ T" G- ?1 T8 b' }1 e" L - 14 {; n9 O/ @: p+ U3 U, i
- 15 scanf("%s",&dat);& s9 I8 r2 R8 l8 v5 L
- 16 if(dat)( x* D/ {4 k3 f3 O- g; S
- 17 {
$ W$ G3 l8 o9 ^$ I - 18 ptintf("your input is %d\n",dat);
9 j/ ]+ E9 N$ V( v - 19 dat = 0;$ H" h3 v' B0 W6 c5 H: N
- 20 }
. ~+ m) |9 s0 L* L - 21 }
/ Q; Z. R' p9 U& E7 Q+ ?" k - 22 }' n( S$ u+ S+ @% f/ {5 b6 P
- 23
6 ^; Q+ |3 s4 m7 Y - 24 //重定义printf功能" {: n3 w& x2 ?; O0 {
- 25 int fputc(int ch,FILE *f)
/ I7 W4 b" i: m6 S. n1 K - 26 {
9 i# b3 P0 Q8 D# [ - 27 return ITM_SendChar(ch);# k, @# @: t# c7 o
- 28 }) r6 g( k( x; y- I5 u
- 29 //重定义scanf功能
- u! X% c$ s! I9 Q+ ~2 ` - 30 int fgetc(FILE *f)
* z- O: S) e/ b J - 31 {' \6 X! o& _) k- a) }$ ]
- 32 while(ITM_CheckChar() != 1) __NOP();, l4 |, {. y$ _$ s
- 33 return (ITM_ReceiveChar());/ V2 C9 X* [$ X" _( K0 H
- 34 }, n+ r- r1 i% |- [& P( j9 m
- 35 4 s. y1 \4 U I& H- ]% d
复制代码
4 E @: F O# R( ^& q8 {- P 7.功能窗口: 可使用以下两种方式查看打印信息:
* n# m9 O( z& K1 b1 N8 x a.使用keil debug功能。 # m$ i" _) n! y
7 B# M' B+ m: A
|