定时器计数值的确定。
; h8 U; V# d! ~/ x! k4 q$ N
+ D6 q7 q# P0 ^( ^3 A2 o TIMER的时钟不是直接来源于APB1或者APB2,而是来自经过APB1或者APB2一个倍频器后的时钟。当APBx的预分频数为1时,这个倍频器不起作用,此时定时器的时钟频率等于APBx的频率;当APBx倍频数为其他数值时(即预分频数位2,4,8,16时),这个倍频数起作用,定时器时钟为APBx的两倍。例如AHB=60MHz,APB1为AHB的2分频,即为30MHz,则挂载在APB1下的时钟的频率为60MHz(2倍频)。/ p1 R" a* e1 a% X* {
2 C3 t7 K T% Y6 h/ v: H1 ]$ a5 t
) l( N# z! i Y8 ^7 R9 d$ ~
7 i! {4 \: Q2 m各个功能定时器的比较表。
# G# }. ~; @& ?3 h' K t, c1 O" _7 y* K% a, T
Timer分布
2 k" r4 |7 Z, P2 o# Z7 D
% @& ~, Q; o# x- z. U& x/ N x( v8 ?2 x {6 g1 N
3 d: y3 s0 X: [' {* X" l, [
# P1 _3 y4 \$ M2 ^- n8 O7 Z* S
s8 V# I% N- Y9 Q: C1 i
; Z+ t @- n3 s) @* B5 g0 h# y3 b, v
( w- {7 _" z0 d s, G! l# B4 ~+ s
3 R" X# ^3 k7 ?, A+ S/ I8 ^- [% H
3 G3 R: N# a5 R4 f
systemtick的时钟直接来源于AHB,而且是24位的定时时钟,一般常用在实时操作系统中。定时非常准确。以下是systemtick的配置函数,由专门的中断void SysTick_Handler(void)。
. A5 |$ z W& r: m$ G, Z) [7 U) R( ?
/**, d' o7 _5 s5 k3 s, {$ ~6 L' J3 S
5 E% E3 \5 Y' ?# c+ k7 S9 u. D
* @brief SysTick时钟配置。
$ T% m- L, H- b! K" l' y, `. X/ ~6 s& ?1 f0 O; m) A
* @note 调用的是系统中的配置函数,将其函数名改掉而已,便于统一管理。$ z2 l5 {7 I% G- A
' _- W5 N% n: ?3 _% Q+ x * 只需要在该配置中加入计数值即可实现任意时间的定时配置,包括1us。
( U- h; W$ f8 d0 h3 S) n. I. G2 i5 S' T+ ^- E [8 Y- d+ B. w
* <h2><center>需要结合中断函数。7 ` T6 c0 r$ N* P W5 ]( l$ T
6 X7 a. b; {7 J9 ^4 d * void SysTick_Handler(void){···}</center></h2>
3 F/ n) ?% f- ~' s9 N6 Y% x7 N2 Q, P- `3 s( p' n& @
* @param ticks : 计数值。该计数值可通过以下公式求得:AHB_Clk*需要定时值,1 V0 ]1 n* t( `& O
0 S: K& F3 U" l" g4 d/ A * 例如需要定时1ms,且60MHz的AHB,则计数值 = 60MHz*1ms = 600000。
) i8 D3 _4 S" N Y
4 v3 D" S% w) Y# w * @retval 返回配置是否成功标志。
% e) q& C& [0 I5 K
9 x( }. b- T* w& {8 R: [ */! J8 K3 K% K2 l: K
, u- K& ]' l, J5 H$ } g
60MHz AHB1时钟systemtick定时中断。5 s. z u8 y v6 B' a& i8 e; A5 {- m) C' v
& S, Q, P+ h8 ~
- uint32_t BSP_CLK_SysTick_Config(uint32_t ticks)
" p4 v# d/ ~. `4 f G' A# } - 4 j' I3 @& y: H$ p3 B X; w
- {9 d* s9 F1 q( c. L" A# m
- % E4 t- x3 F4 u7 h
- if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */7 o5 w# `- C" ^( m8 L& G
- . d6 j- o8 Q8 ]$ o2 |) n. N4 f
- ( z' \4 X( l2 F
- ! W6 B) s1 o9 X; j+ Y: y$ {. B
- SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */! q; t- q$ _' X" u# ]! Q: e
5 l* v* ~! u9 l) T- NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
% o1 K2 h0 T- b' w6 B# a
. J$ \5 H9 Z& {# [( R0 G7 a- SysTick->VAL = 0; /* Load the SysTick Counter Value */
6 q W0 ~. u) m$ x2 a - 1 r6 g3 h; \4 f8 f- d
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |) n9 g+ J! d- C% a6 F0 e3 g& w
- % t9 b$ A3 J' \3 k; y2 F; ?
- SysTick_CTRL_TICKINT_Msk |
{( E3 v! I5 h2 |
6 _7 O, a4 H* v2 n i8 c- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */9 X, Y2 V$ [# G
7 S* e: R j* Q* \- return (0); /* Function successful */
' {3 S1 F0 C. S& N% p9 p
, ~4 |; i) m- H) N$ q- }0 w% T9 e% m4 ~
) |- @0 l4 x3 p5 u8 I4 s1 S% T
复制代码 . a) B. J) ?, e x/ J
30MHz APB1时钟10us定时中断。8 u5 L1 i1 w$ w' ^" R% z. F
3 W0 ?' _$ c8 [- X* f2 a% n
- void TIM_Configuration(void)5 F# T' }* x5 E# }$ `2 S
1 F7 @# O+ c( U8 W. L* J- {+ t, A- R2 `* i! t
+ ?* m! @$ [9 ]% x3 p0 b/ j; C- NVIC_InitTypeDef NVIC_InitStructure1;
% j/ L+ m$ T# K) Q
1 R1 O! o5 P5 T, H. u- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
; d u7 q8 y* M8 a! h
7 Y5 @. A: [* O x! W8 \- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);- w% x0 _8 o: `- p8 f! s7 \5 W
- * ` L ?& V3 {0 b; A/ ?' }3 V% }' v
# g5 M( x0 X) y! a: h3 D" l- ; T0 b; w2 G7 p* t. m, {% Y
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);. c* [: w- W* ]( d1 o
- 4 F ^! H7 |( ?
- NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;' d( h3 l: I2 A! l$ @/ x
4 M9 ]; p( j$ @ C8 Y) w- NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0;0 O* ~! Q2 r* h5 L& g/ E) p
- ' b' q1 _/ _$ m) H
- NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;
b$ l7 g0 C2 l2 L - 4 Y( |4 l; r" Z2 b- L2 B3 _3 l4 }6 [6 k
- NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;3 r# x* D$ l8 h
- 6 q1 Z1 Y0 u8 E" @9 o
- NVIC_Init(&NVIC_InitStructure1);9 u8 q$ }9 d) H+ [
: B7 R% s% Y8 O) g9 Z8 N8 W2 w* p- 3 c( x5 n1 o, c7 x- j
- 8 |4 Y/ f4 l( j7 }$ t
- TIM_DeInit(TIM3);$ @1 A4 t% V8 s1 q4 M9 c
" q+ }3 Q: E" k2 } N- TIM_TimeBaseStructure.TIM_Period = 599;
1 L4 A1 _/ R- ~ J, [0 ~ - 6 k9 a* v1 B: H5 y, ?1 _. b
- TIM_TimeBaseStructure.TIM_Prescaler = 0;
/ ~$ w7 N# f8 N: a A! g5 ]' M9 g
( S7 E( |" n5 L$ Q0 [# O- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;0 Y+ k5 n1 R6 A3 R4 @8 x
& V) U/ j/ Z6 {4 s# e- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
8 V q( M0 g/ O+ S0 L - $ a. n: k' u( J
1 G1 ]6 |. u6 s
1 d( K8 `* E% A- I* G3 G- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
# W% C! x: c, w; B( d/ [ - 7 t" k% a7 \$ k+ u( h& n) M; p
- 2 ]( |- h/ n# D/ ^% @! {' U' |
7 l- B) s* B) B$ H B- TIM_ClearFlag(TIM3, TIM_FLAG_Update);1 j- T( I: ~/ v6 ^; ^' C1 g
- , Q: B7 k. Q7 o* j8 `' j
( @+ b7 A9 K* b7 X2 e1 g, ]- c
- x" O( A* Y1 i- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); M* J) F4 K9 l. ?: s/ O" r/ h3 y* u
) g4 W6 S+ l+ W2 `( F, b- ) n- t/ R, J4 w
- : V$ ^9 G7 S( V
- TIM_Cmd(TIM3, ENABLE);9 m% N7 d- C/ J* E! I3 d) w% E3 L
) F. O% L! v7 Z. K: z7 D' @9 e- }
复制代码
8 V$ G& O" \( m/ U& @- Q( A# q: T* O2 r/ {) G
30MHz APB1时钟1ms定时中断。6 k* c3 K7 A, q1 I
0 J$ Z. p% V+ D8 j( b9 r- void TIM_Configuration(void). J1 T* ^) f0 T+ ]$ e, }2 |* c; W
- ' C' u) \" g- N* {1 L. o
- { n7 i9 Z/ X5 `$ ^" q
- 5 g+ a5 G0 p; ? n7 M o
- NVIC_InitTypeDef NVIC_InitStructure1;
4 Y- a3 f& y/ g - ( m7 d/ l: M7 Q
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
) R7 o- s7 \. y. I - & i# e/ e- k$ R+ p" ~7 v V& }
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); h9 s9 w, J ~8 W* J, f. d( h
+ p' K5 O V5 e9 A* b% c, W# |7 m- / L, l( c# y% ~: C
- $ V, T0 v- D% ~7 i' i& L ]
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
- W0 V) ?% z" u* F. r r - . i1 }& w0 b. z7 Y: |2 A
- NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;
! m& r: ~ w7 ^( e
/ N5 U8 F3 K+ a4 H- NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0;
3 T( c/ i' |! \0 O
1 V2 r8 d( r0 @. S5 J/ W% L' S- NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;
- ~1 d" H2 S3 h - 3 Y$ P. e! M7 a
- NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;% k; Q* W. j+ X o2 z
4 {& R* n0 t/ v2 r7 _ v- NVIC_Init(&NVIC_InitStructure1);; I) \% Y5 q$ S& @ p9 v5 C
: F/ W$ h( E9 {2 B7 o2 Q- 9 g$ Q! U* K/ ~. m
- ' U, D X/ V" r, ?! E9 Y
- TIM_DeInit(TIM3);
9 l7 j: t8 C M1 h, W5 k
: ?) u* l% L6 ]' ]- TIM_TimeBaseStructure.TIM_Period = (60000-1);; e# z* l* C# d) U% f- u3 u1 a
7 @, Y$ _2 b6 r, H/ V- TIM_TimeBaseStructure.TIM_Prescaler = 0;
/ p4 x. z$ f6 u9 { ?6 e/ o+ i: i
1 D% X. ] g! ?- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;* m3 v5 b7 H. q" J9 @2 n- u8 K9 o
- ; U" Z3 b* K. r. K# i, k8 p
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
3 I: r4 Y, g* [: g0 ]8 C1 B% k - 8 F# H6 d& K1 d
- + S f# h. F$ Y" u
# W# ]4 [" F% F1 N7 R4 a) R- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);. _! A# |5 g4 g9 k" t$ ~& u. r
9 z3 A) E9 d- C
) g( ~( }% J' ?+ `' ]) Q7 _
, S" m' g: t( R$ e. @" G- TIM_ClearFlag(TIM3, TIM_FLAG_Update);
# w. c( w8 d2 I# ^' } - $ F3 W, y( b% e) C
- " K% M1 P& H2 R9 n5 T0 W
- 3 f( ]" Q6 d( e! x' T( |
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); J9 M6 }. V o. `# @# H
- ; o# Z7 D$ A1 _3 g4 r. O4 k& T
- 8 U4 a4 G( L' D" }
- 0 n& q$ a! B0 _ i
- TIM_Cmd(TIM3, ENABLE);9 \* {& I2 B% }
6 D2 T7 j" h @0 B" f! N7 J% X$ [- }9 Q- X2 i. d+ K t9 @6 G
- . K& Q) L& i3 O3 C
复制代码 ! b; V" q) [: `* g6 ^
|