定时器计数值的确定。! b/ c; g! e. A
0 z8 i: t# R X% p1 j TIMER的时钟不是直接来源于APB1或者APB2,而是来自经过APB1或者APB2一个倍频器后的时钟。当APBx的预分频数为1时,这个倍频器不起作用,此时定时器的时钟频率等于APBx的频率;当APBx倍频数为其他数值时(即预分频数位2,4,8,16时),这个倍频数起作用,定时器时钟为APBx的两倍。例如AHB=60MHz,APB1为AHB的2分频,即为30MHz,则挂载在APB1下的时钟的频率为60MHz(2倍频)。
( t1 j4 ]& z3 M7 ^
4 u: i, S- C$ f z( } M$ L+ \+ T9 \, o" |
/ C$ G0 q! o& V* m6 R; j各个功能定时器的比较表。
+ n; f7 t4 X Y' F0 p+ q
]6 s/ k0 W4 U1 G, H6 W' e" xTimer分布0 [( L8 z {, H6 H# Q
3 V) i4 V- K: d% }: C. Y1 a4 X
% Y- C7 i5 T+ z8 C6 b
" C* y9 a" |0 F) E6 w# ~
V# P" r. o+ z& f" F+ x
5 O# ^* Y* {* O' E0 `" x8 n5 ]2 S( J& S
7 d( @' J/ l5 o1 T: b
( ~9 [ P* b. ?/ i+ b
% V/ C# X0 C( O# M& H$ R$ e) q
' @& Q; q- D* ^* b: ~4 A R* G( f" y' [+ [7 F3 Z# X
systemtick的时钟直接来源于AHB,而且是24位的定时时钟,一般常用在实时操作系统中。定时非常准确。以下是systemtick的配置函数,由专门的中断void SysTick_Handler(void)。
2 P/ U1 F. C7 J
& m6 a- D5 C, k8 Q/**
8 |2 P$ R* R/ H" ]# u8 V3 S
' I9 c: A! l' @( B/ E * @brief SysTick时钟配置。% W/ e( _6 `* _7 F# s/ e
! ?7 _1 a9 w) Q# q5 J/ ^# x * @note 调用的是系统中的配置函数,将其函数名改掉而已,便于统一管理。' b1 b/ ^( Q9 N; O8 d; y( s8 D
. P+ H2 g# x* u* T) |& R
* 只需要在该配置中加入计数值即可实现任意时间的定时配置,包括1us。' o, v; y7 Q5 T8 m/ v; s
t' R9 @* t4 P8 n. V * <h2><center>需要结合中断函数。
0 k7 v/ o+ i) {# j0 O- c' m
1 P1 _) ]2 P' E * void SysTick_Handler(void){···}</center></h2>
! [, Z! I r/ v7 v% ]9 H* `, z, L
+ i( n, ]1 H6 C. l8 p8 U * @param ticks : 计数值。该计数值可通过以下公式求得:AHB_Clk*需要定时值,) _0 K7 j; M ~4 N' n0 v
; Y! W5 K6 S8 V+ O
* 例如需要定时1ms,且60MHz的AHB,则计数值 = 60MHz*1ms = 600000。 4 R3 b' b7 H' J5 N8 ^+ W# {
; G7 J/ v& r3 W! _! ^
* @retval 返回配置是否成功标志。
# D. r) I7 }2 ]# U; K3 K% e
. `3 D V, w E7 a, ^ */. p9 } S2 O$ _8 _3 o' y0 h- K
: M/ [; ]: ]4 L
60MHz AHB1时钟systemtick定时中断。: L- \9 m( ~' i0 L
a0 O; R3 g. N- uint32_t BSP_CLK_SysTick_Config(uint32_t ticks)
3 F) U$ }: B% s: H: U/ @( J& |
7 y8 Z2 P, J! U- {
$ f8 p; `3 \7 P- F4 Q9 Z& r h: k2 D - + j& z- k" d$ J5 R& G' Q- X
- if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
& i% D" p& J! N8 _' Z - + c% C' i' ?; ~: f* Q3 b8 N6 }) F8 w
- - k. [, s. E' |. ]" N4 @
- / A& |" ^: O/ A5 n
- SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */; c y- n, z+ n% \
- & }& I7 L9 e! f: ?3 h1 u' H @
- NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */8 J$ A! ]( j' d! \+ _, Z
5 A- A' C8 k% c5 g# }0 b" T+ V3 K- SysTick->VAL = 0; /* Load the SysTick Counter Value */$ ~+ ^( u _$ A% r1 j
- L1 p( J9 S/ k, K$ [+ v+ d0 o- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |3 C% H, B$ J+ G' _8 q
) h; ?1 T* @- }- SysTick_CTRL_TICKINT_Msk |
0 {; k- y2 x* X% i' u - + o2 |% k! m! \7 f0 Z- J
- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */3 ~6 X. S& |1 |9 m, k& F
- , f2 c. a/ Q3 J
- return (0); /* Function successful */$ F' P6 r; P: \7 m
) R( L1 m! v: T2 k* p" p) o- }
) I- g0 r8 Y. T( X8 x
3 C+ H: \# R- h& k8 ^' H
复制代码 4 _7 |; Y% D5 E
30MHz APB1时钟10us定时中断。
1 {- [% H8 F( U& m5 G2 |7 t# l/ A) x: Q" x# ~ ^
- void TIM_Configuration(void)
1 o' E# O- u9 ^3 Q; Q+ D
# t) X1 |: F+ |- u* e4 j- {
M. L4 E) k+ v7 ~6 I* X - + a e0 l7 h" R# a
- NVIC_InitTypeDef NVIC_InitStructure1;
# t" ?- B, ?1 ^9 E" K' @
2 B# k: s! H+ P" F- g- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;. U% d- Y7 z+ K+ A _
& d3 v" i( N3 W8 M) ^- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
- p" o7 e( H' R# o- L8 O1 ] - 3 _* A& s% ]. o2 ~
7 X/ |; r0 N, h' {8 [' |# B' F6 [- # r# ?% b/ n2 O
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
8 w8 Z2 p, P# y) D+ Z
+ ]( ? A, w) ~2 u5 O( N4 K! ]+ B- NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;; K+ {2 h# n8 |( e0 ]
- 7 o, S* x9 H% X% C' S$ ]
- NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0;! f$ b% _; ] v" r5 G
1 t. h. ~# L0 ?! a- U- NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;/ H. n: K r9 u
- * F9 B; z% `: ~- i( {" X" W9 c! _
- NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;
P7 L9 y. B% y5 T
+ m1 B+ |0 l0 G% _4 w' z# T$ i- NVIC_Init(&NVIC_InitStructure1);# ?! D0 i# K8 a$ q" W, u
1 M4 I4 |7 I( }- $ b! M, G. s' K6 x y: x9 c
- & |" Y- k# a) d h
- TIM_DeInit(TIM3);4 d3 E3 g1 z8 H% A6 B
2 E5 ?# k5 r }) p9 q* l- TIM_TimeBaseStructure.TIM_Period = 599;
. e7 Z) Q% o" R) g$ j7 M - ) p6 l! N7 O* t$ T) W& a& z0 V
- TIM_TimeBaseStructure.TIM_Prescaler = 0;
# D. v" K& m( j7 j) k, B - 5 |0 R) X9 t7 M4 Q# ^6 _4 F
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;: n4 b6 v- A+ q5 O) @6 C
- 5 \& P) P& b* a- o J
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
R C' H0 k' G: U# W" p5 ]
& k: v, B4 x4 L- ! i4 E, q# Z; e
0 | B, [8 j, U# D& t; _9 j- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);7 [/ @# H- f1 z
: U( M O9 B1 Z' {# o6 @1 q# b
2 H1 G8 F1 L' e* e- 7 [- [8 Y) |+ m* E- O
- TIM_ClearFlag(TIM3, TIM_FLAG_Update);
: ^2 @2 k5 B4 ^- p1 O ~
4 w9 `) V# v& R% ]+ n2 [
% J$ j* F& E* T. V, N
J @" r) E. t- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
' o8 q$ Y, n3 ]8 w; t( p* S, J( b
2 q3 n" ?7 y2 Q }- # X) Q5 _% p+ N1 K* r! z/ N
& F* m9 K8 l, [6 I0 K- TIM_Cmd(TIM3, ENABLE);0 s9 t; Q O7 X$ i. P
- 9 D, E$ v* j4 \' Y. X* m9 P7 p$ c
- }
复制代码
( L; w# c& q6 P+ E) W2 \7 K- P' O" A
30MHz APB1时钟1ms定时中断。
! ], K3 J1 q3 b6 K/ B4 G5 m7 c* H4 S( P; v4 \% W3 S
- void TIM_Configuration(void)
) ?0 L1 N1 Q3 i1 q5 S: p/ J
& W9 [/ E8 I5 v. e, k. M& Q- {
, ^3 q$ Y3 w8 e, O& T8 z+ n0 r. c
0 P' z5 r9 \$ ~4 n' ~- NVIC_InitTypeDef NVIC_InitStructure1;; g4 ^- P5 G0 d
- " y3 P/ _. [, t/ W
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;2 X1 {' b o) {% J f) B
# O- b- D9 y( b& l- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
- z; K" ^8 N$ q: I) p3 n
( P, c! K4 N6 X9 i
: ?1 _8 G3 ]& T& k7 y
' n; X! q3 H( ?$ }4 l H- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);7 n/ S* D3 Q7 Y7 z+ C/ Z
- " j! R Z5 Q, l% u! V
- NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;
, K. H& J' @3 d: r3 y - 2 e" k% D% G4 v7 |, Z
- NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0;
' H! g1 Z; a* J/ v: C: f+ A- H
' s9 [ ^8 Q s# _0 K. \- NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;
0 E" j2 A) c; h; Q - - T& B" R% }. F: |
- NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;
E- B8 j* d7 R1 d S& g7 F; ^ - 3 G0 ]* B, e1 `, `) |7 X: w6 _
- NVIC_Init(&NVIC_InitStructure1);. n- x* X9 @: T- H- a) r6 n W
0 ? J! O% d4 ~8 g- , I. O7 v! h5 S# S& W2 R+ m
1 d' c. {( f( e- z. ?; f% b- TIM_DeInit(TIM3);' E0 t; r9 W* M% u' x8 T
$ a) y) L2 n; h3 W" \9 \/ ^- TIM_TimeBaseStructure.TIM_Period = (60000-1);
7 p" }. o9 z- k$ }3 T L w! Y. i ` - ' Z* B- c& o2 G& |
- TIM_TimeBaseStructure.TIM_Prescaler = 0;
1 c F2 ]. u% \
; K5 `( P# |1 {' `3 U, z- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
( ~8 y; x; Z- t7 ^+ T - 5 `. T: H3 r6 }- i6 D
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
" ]: V( O3 a* g5 m% y# b( ~
4 Q& T* y3 @5 k, h1 u& Q4 s- 1 B4 |% e- U& K/ g
0 l* g) C" w9 Z/ X2 H5 ~* O2 [& m- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
( d6 o2 i9 K& N" R; l3 p - " g: ]. J2 ^# y! O5 z" t- A4 H/ r' w# L
* ` U4 h, K& v! t1 O9 C
: q X" {0 k S+ j- TIM_ClearFlag(TIM3, TIM_FLAG_Update);/ H( n- w( n- @/ g) O9 z$ A
- ! q7 [7 I0 p$ H2 b' n" s8 f
- * |$ _) ?$ O5 b/ m
- 8 S! e g1 w7 ` h
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);8 d6 r3 h6 f% Y5 N* d. @) o" e( }
- 5 q5 v5 {+ \ g. x2 V
- % I' Z+ A0 ?: h" S9 y
% P8 W$ _0 W- r0 L# t% q4 \- TIM_Cmd(TIM3, ENABLE);& p. j8 k* H$ j6 f
9 J. e" y9 O8 k4 o. u- }& K6 ^! S6 s3 b" A) C4 m
- $ E& I' v: t# Q4 A
复制代码
# x) K/ I M/ p |