定时器计数值的确定。
# M& H1 ^5 t& F
3 Z/ i: m2 w- u! ] TIMER的时钟不是直接来源于APB1或者APB2,而是来自经过APB1或者APB2一个倍频器后的时钟。当APBx的预分频数为1时,这个倍频器不起作用,此时定时器的时钟频率等于APBx的频率;当APBx倍频数为其他数值时(即预分频数位2,4,8,16时),这个倍频数起作用,定时器时钟为APBx的两倍。例如AHB=60MHz,APB1为AHB的2分频,即为30MHz,则挂载在APB1下的时钟的频率为60MHz(2倍频)。# X" ^4 p: p& b0 Y- h6 \, c
2 z$ N, T; K# U8 L6 V/ t d% N4 o! I# V, I
# U1 q% |7 R" s F E* Z2 {各个功能定时器的比较表。( ?) S7 k1 ?! v
0 C. A" x2 m" [ O' T1 z; `Timer分布
( x: V/ V/ x7 H! u- q8 n; v$ K Z
) @9 H5 c$ H7 \
7 p1 w: L; a& M. a, q$ z3 [& b& d: n6 D
; |! f$ I$ I H$ Z
! C. J, A" n4 ?0 N9 [7 g) Z* L
2 b6 c" i/ Y; {+ F# b2 ]* D. `
: z: V: A' i' U9 F( k8 f. G. _5 i- Y9 [ M; p; B$ j
4 \9 c6 q" ^- p; w: _
3 _' ~- X6 g# {5 ]
' L9 ^$ |* P( N2 {; h" R
systemtick的时钟直接来源于AHB,而且是24位的定时时钟,一般常用在实时操作系统中。定时非常准确。以下是systemtick的配置函数,由专门的中断void SysTick_Handler(void)。5 o2 D2 D5 j3 F$ m
# e4 t$ F& ~$ W# _; ?9 \
/**
& B o0 [, I/ s' T3 T5 U
A" p: ?" R* s6 U4 o& Q * @brief SysTick时钟配置。: V6 A8 g+ \7 h0 @9 H, Y7 ^
, @! n) g9 t% F4 j5 c
* @note 调用的是系统中的配置函数,将其函数名改掉而已,便于统一管理。
+ `3 n0 c! [9 N/ d+ U4 {
$ z7 h% N* S- y( J$ d- @6 F * 只需要在该配置中加入计数值即可实现任意时间的定时配置,包括1us。
# F* R! I$ O* }- a4 u2 k; H0 a4 ~( d# ^
* <h2><center>需要结合中断函数。
" l( d+ c' p6 ] e1 B
1 v& y2 t$ k- Q- d: E * void SysTick_Handler(void){···}</center></h2>) I+ ~6 f2 ^7 b( N! n
% c8 O' U% a) g# R; K$ I/ `6 M: A
* @param ticks : 计数值。该计数值可通过以下公式求得:AHB_Clk*需要定时值,
8 _+ v$ M6 K/ E: Z8 O! `& f4 l5 b8 @6 l# ]: d
* 例如需要定时1ms,且60MHz的AHB,则计数值 = 60MHz*1ms = 600000。 - j# @! U: K4 N9 |2 g
" A/ `/ v( K$ K
* @retval 返回配置是否成功标志。4 h& K* |- b G- @3 O8 l: \
3 v) N5 `# _# E* l7 S: d */
3 D" E8 N' l3 w3 p- s, _) O% P5 ^5 g9 {' t
60MHz AHB1时钟systemtick定时中断。/ b% a* G0 Z' W) \
# I. x4 A6 V% y
- uint32_t BSP_CLK_SysTick_Config(uint32_t ticks)
7 G: L9 U: C) `' X
" ]6 \; c6 F3 a% L4 v6 U( m$ t- {
' Q& W) N7 | H+ x8 S - ; P O" ?* Y0 u: }
- if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */2 P6 Z! V! P0 Y/ I
& [4 K7 Y. Z+ Y/ u% [! d
0 r7 C& c: Z/ o, J0 B- : x q& v. K5 \
- SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
" s5 K# ~7 \& E$ w# H3 | - 0 D; K0 ^8 q2 W1 f8 V3 H
- NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */. U; q2 \* n( k2 b1 i
- & O4 G X# d# v" @7 l8 O
- SysTick->VAL = 0; /* Load the SysTick Counter Value */" F( g- I: @ x1 m* |% {% i
' J% W# P' t' Z6 q0 Q9 `8 _- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |7 C2 p6 y- X4 P; s: P
5 T) f E6 ]0 ~1 s& T- SysTick_CTRL_TICKINT_Msk |1 ~3 J" t4 I+ a1 y; ?/ b
% R8 w9 \( j6 G. [- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
) S0 n0 p8 r1 h$ `* O+ c - 7 y6 K* M; v* A; K q% S
- return (0); /* Function successful */
5 l$ f4 i% ]# R - 7 Z: r% G+ ]+ K k; s% K; Y
- }7 E6 G2 w ~( ]' o, ^
) V4 I/ ?4 ~" N4 Q# }0 Y# O
复制代码 : j# M4 o W/ L& a; L3 [7 L, _* k
30MHz APB1时钟10us定时中断。% n# f; Q. J7 G+ p( y
, [. ?, H+ s4 b3 j4 U7 R$ Z, z
- void TIM_Configuration(void)0 o/ Q9 D" [, P# L
- 8 ~6 d( c8 X! z7 X
- {
" x9 ^) g9 I/ ^/ }9 e+ k5 k3 C - ; t! J7 V! G6 E9 I7 O' E
- NVIC_InitTypeDef NVIC_InitStructure1;/ }+ M, ~; } T7 }# ]
- . \- `' r: S& \- i
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
3 p3 J9 M$ ?7 a( \ - 7 j' a/ G& o+ c* A
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
9 g8 i! Y6 }4 Q7 q* g
$ m x. k/ V, O9 [ j- u7 \
0 K' U; o( j& S1 G: S- " j" ^- w3 v: w) f8 f' S
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
7 E; T! u! I" `2 V
$ C) {" f* `' Q2 ]( S- NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;/ \7 u& h' s/ }
/ {- R; z' Z ]( R/ K$ \1 s- NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0;% s; b6 Y: {$ B
" h& W/ c0 u9 f1 n% H7 C- NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;0 \$ x; e1 y( d
& Z; T! q, W% C' h0 D- NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;; J. [+ t3 g( K4 c
- 6 c8 {: ?3 @5 @' A' t j
- NVIC_Init(&NVIC_InitStructure1);
; @ \7 T) t, W8 p1 B
, N9 S. `' z) c- 4 n8 Q1 P' ~1 Q: h' P$ e
; @- H ~# ~: }9 T) w, U: h2 j- TIM_DeInit(TIM3);
( O0 V+ C: V7 S, _/ R7 C - 9 R5 e5 ~& l) t1 \" E7 R2 |* I
- TIM_TimeBaseStructure.TIM_Period = 599;
, u, `' f6 i# I+ F a& e
6 V% i' ~, ]- y8 N0 K- TIM_TimeBaseStructure.TIM_Prescaler = 0;
: k) a R; J0 ~" H5 \2 b
" l5 {: Y- k$ r) K: s* j1 i- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;) i, l h: o& H/ K9 \9 e- Z4 e
- _& y6 ~7 d, r- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;6 E1 }1 C& w- i* o& r- V0 G
- 4 { [& S' g5 i& y
- " _. R) _% f- K' r- K- x
- ; k( |3 S7 l. z
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
- J* K: O) K- F# b. G$ o4 {
* |% W" L. X! d1 {- + t9 O+ b* E( q$ u
- 4 C+ N' _5 T/ \: j8 q9 m z+ A1 l
- TIM_ClearFlag(TIM3, TIM_FLAG_Update);- o/ h; V2 p8 `
6 @* L9 v5 i3 {- ; b& T, w2 P2 M
- 0 h2 x/ Y5 P$ @8 w# R1 P2 y
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
& [9 \' h$ u o( z p - 6 M6 m5 H2 \% U) s
/ z4 }% `, q, M: J1 S3 g$ c+ E$ {* h& O
8 ~* V. _% k/ f- {( A3 L% r4 V- TIM_Cmd(TIM3, ENABLE);1 w+ n! T1 G! y G
- . q8 _ J6 N5 A2 F8 L8 H
- }
复制代码
- q) r7 w7 [5 b) L% T3 C( k& Q* x% a/ [4 ~: r( U% j
30MHz APB1时钟1ms定时中断。( N+ u5 u; \, h7 O
( y N6 H |6 S( n( v
- void TIM_Configuration(void)
* G2 L7 R, a4 B) G5 c7 r& b" v+ D - ' U4 P$ |8 G( A8 N" {
- {' ^* Y4 h, s5 x A: w: a7 D
- , v8 x+ Q$ z# D S
- NVIC_InitTypeDef NVIC_InitStructure1; E5 d: E, X% I/ r, p8 U6 U7 M
& X/ F; y$ d A7 O, N/ _- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;" `1 Q2 W& k. K$ R
- ! D' Z! @3 |( c' N w
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
, y5 W3 k2 {1 K9 c5 q - $ C5 z% {. c4 U0 I4 z+ K( x& y
- % @, N# Q& o9 `" h; i9 k
a+ G' S! e0 ^% j+ t) F- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
; H7 O- `+ d$ ?: }
: o4 ^+ z8 S; l6 m F% e0 o, z- NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;
- u6 d9 q+ V! v! { - " Z _1 ~* a" C+ e1 \7 D. r
- NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0; \5 h2 \# V2 k3 r) X9 s, h
- . v: Y" ]* g$ j+ ^$ N5 G% R6 d7 n5 S
- NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;
. C6 E! [2 o6 `- Z6 x5 V - 5 c) z" [5 V7 t* R, @/ G5 g3 |
- NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;0 Q* o4 f2 q4 A" Q1 n
# V+ @' p6 i4 N% U- NVIC_Init(&NVIC_InitStructure1);
3 s2 v0 M; ~* }/ {# `- i8 L& _
2 s4 ~, K0 D2 g8 {, O
' X% q) ~1 `, \1 o. ~$ x/ G- 6 }3 H* ]3 T" t- j( _
- TIM_DeInit(TIM3);4 E1 A. l( O2 Q6 h2 J
- c$ c% d* m% ]7 j7 X& ^% d
- TIM_TimeBaseStructure.TIM_Period = (60000-1);; W* d, d& n ~$ e, c9 r
& o( P2 l# ^/ m& U z, }- TIM_TimeBaseStructure.TIM_Prescaler = 0;
) k' {' E4 S: S( V$ ?+ {" N - 6 A0 \# y8 {% `# s: ]$ Z
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;7 p6 O9 A; b2 U" g8 ^# V
- + k* t/ u+ ^2 J9 _: S
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
" q# p, ?; I; C# }( x - ( a. H% M7 q9 F" G
' w( Q& _9 w6 y" x- ) y" c3 Q, ]1 [/ }6 k+ B0 S
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
0 }0 S( X+ y! R/ s1 R1 l2 P, \ - 4 b- A* t) ~% z3 o. N- B/ ]
0 C; L2 n6 T& B- F) R
$ y& n. ?1 m. b; y- TIM_ClearFlag(TIM3, TIM_FLAG_Update);7 x+ u+ _: R- V0 O R4 U
- * x) r* s* X( A+ ~
- . X8 G; L: R( x( X
- 7 ^; @% x4 w4 ^+ T+ r' H
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
; W3 Y8 Z7 w% ?; t* }" y) U- y
# |, y- W$ M0 v% w- |/ i. _# ?- # T# r7 }' z) j% y2 A' l/ P
- 6 s' A2 m% f$ |5 j( k4 ~9 e
- TIM_Cmd(TIM3, ENABLE);
4 w# y" R; q" g( M R! ^ - $ C# Z* m) r: R9 N* f
- }1 j. {0 Z- J1 m }/ J) {
- # }4 S/ C, |$ `
复制代码
3 T6 s+ \1 B' l9 g |