定时器计数值的确定。0 z# }3 ?3 u. @, F. p6 x) b
' r( j q" t( _1 O* ?5 F
TIMER的时钟不是直接来源于APB1或者APB2,而是来自经过APB1或者APB2一个倍频器后的时钟。当APBx的预分频数为1时,这个倍频器不起作用,此时定时器的时钟频率等于APBx的频率;当APBx倍频数为其他数值时(即预分频数位2,4,8,16时),这个倍频数起作用,定时器时钟为APBx的两倍。例如AHB=60MHz,APB1为AHB的2分频,即为30MHz,则挂载在APB1下的时钟的频率为60MHz(2倍频)。" n/ n _/ d, P, u
# J6 }! q# A6 s; p# a0 n
" ~$ t( a8 X t" V6 Y/ w: B3 ]" \/ j! O& Z
各个功能定时器的比较表。
% V! y2 G. A8 d$ E/ U) [7 N+ ?: U( J' h6 `
Timer分布
- T4 q- U, o( M n, R' f% s" f- u3 V$ x6 {+ X
. R) y6 D6 P! F: Z9 W* F
: V4 R/ I: y4 j. {3 ?# k
% {: H+ H T8 p( u# I% I: @: v: S' R, ^ m1 e
$ M! B a# I3 o6 S
7 ]+ L, N* C0 k
1 J& m8 n p4 Z: u" ?0 `+ Y: A2 ?1 I2 ]8 y; R
9 d4 Z( _3 c! F* h5 K/ L2 W
0 |2 p, i% m. K" A
systemtick的时钟直接来源于AHB,而且是24位的定时时钟,一般常用在实时操作系统中。定时非常准确。以下是systemtick的配置函数,由专门的中断void SysTick_Handler(void)。) X4 P! Y4 g: f9 t7 H
: s) A4 x' \5 Y
/**
% T7 @7 k H/ [' D+ v2 v
& B9 @9 b; l! J- w; I * @brief SysTick时钟配置。9 `8 Q" u; z R
0 P% G' i8 c7 A# {8 e* j/ X * @note 调用的是系统中的配置函数,将其函数名改掉而已,便于统一管理。& m, I r7 }* B' b. L
0 a- U, o+ U% X8 M$ w
* 只需要在该配置中加入计数值即可实现任意时间的定时配置,包括1us。
' f. n1 Y5 y/ P
V. \! Y, A! E4 s( S( T) | * <h2><center>需要结合中断函数。) p! B% r6 W% R) q* J9 [
! P0 }( F$ f7 ]) ~ * void SysTick_Handler(void){···}</center></h2>8 x2 x9 E( s# W/ r$ n: q7 P+ F7 Y
- q. A+ ]4 P# j$ k+ w) }* `. {, X * @param ticks : 计数值。该计数值可通过以下公式求得:AHB_Clk*需要定时值,# J3 w' _* u; M+ L! S/ |
2 A1 ?9 P& D! U0 z) b+ _3 F/ u * 例如需要定时1ms,且60MHz的AHB,则计数值 = 60MHz*1ms = 600000。
a4 R9 m* A9 g5 G9 {- l+ ?, X. P( Q
7 o' e4 G5 h# Y) q4 w6 A# i * @retval 返回配置是否成功标志。1 ^2 y: i- X8 g7 E" z r* X% @
5 r# H% Q9 I' _- O3 K4 } */2 I8 E Q2 @) l7 J0 u
2 b2 I1 ~/ y$ B2 M6 `/ F2 P& K
60MHz AHB1时钟systemtick定时中断。
( _6 s9 V- y- q! R! I- f6 x0 T- N+ d1 A
- uint32_t BSP_CLK_SysTick_Config(uint32_t ticks)
! }7 O; z) |; @- f; ^/ k - 3 I+ p) o: U, h7 O5 }
- {
& R3 x* q& d# ~% ?7 y1 a: ^% q
4 r! F9 a* P; I7 n9 T- if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */* o2 J4 d0 j' E; q
4 Y0 s$ m' }8 D6 r/ s- 5 ]% e5 M! T& P0 A. M& y0 J
- 4 @9 i" r4 B: x- o" q) L% o
- SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */& G4 ~8 q) C* J: M% Z
/ {% p1 I. ~! l! u- NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
: l4 D$ Y" p7 w) D- F% v
! J& }. F% `1 a4 d8 e7 [# L- SysTick->VAL = 0; /* Load the SysTick Counter Value */
7 f1 m8 n8 e. n
5 }2 ^7 y# S" y( k- U- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | s2 Q5 N1 a1 i
# @5 X; Y& z8 j4 _# ~- SysTick_CTRL_TICKINT_Msk |
+ `' s2 a. N4 g8 S# C- @& ?' Y
' `- P. L9 ~/ g9 ~* `5 M- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
# b g0 N! {8 {3 a, }4 O4 q3 s# r- G - 5 v9 y+ o7 l0 ?- y9 P2 I7 G( ?
- return (0); /* Function successful */5 k: c# b8 P* f3 P' h( r
, i: _4 h- F- S9 o- }4 t% M* h. j3 N) V6 ]- ~) p w- c
- 8 N/ E8 c4 h6 S+ `4 m) \% N
复制代码
# c% H c$ q, J30MHz APB1时钟10us定时中断。
0 n* }+ w$ N9 T4 u
1 d% f1 Z" n1 r$ U/ p' x* }- void TIM_Configuration(void)# s: N# P/ k! D
- . r2 C' M/ ?, x T& l8 r$ Z, L
- {* Z. {9 x* p& M) e; O y
- , W* _- Y% K: D3 _' M$ N5 t2 S
- NVIC_InitTypeDef NVIC_InitStructure1;' [. C( m) R7 [ ^
: N; E$ r8 t# {. X. A7 m, t- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;5 H0 k$ U/ w" X; P
- ; ~/ g" o/ a( l3 r7 J- P3 v( `* z! d
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);1 g; N- l+ x. L- ?
- ' T& c- _! R- N/ u
# S W8 X% M/ H1 B- 4 x$ o+ h' s. ~5 ~# M/ a
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
* _: |9 Q, @ ?" `; q
7 |& _# \5 U4 ~9 j/ s: V- I- NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;
" a0 M7 q- Q$ j2 Q- j- y! N3 j4 Y - : K ]# L S2 b* k- ~( i
- NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0;
8 j0 P r9 s$ r( o, s+ Z' e$ F: ?% u! x - " W, V0 D3 Z- X" W5 v% C, J1 ~3 e
- NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;7 s* X. M4 x% P& X3 J) e
- 2 i3 n7 G0 r3 Q% I8 B) X- p6 J( I
- NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;
6 G; y' U) }/ l1 n, v. r$ e
9 p* u2 M- t& E7 \- NVIC_Init(&NVIC_InitStructure1);: C) G* k/ D& b! X
- # l$ I3 p% D5 A6 R. [
- 8 l+ e, {! `9 W
, K) i' \, X% F N# j' l- TIM_DeInit(TIM3);
; Z) ?9 }$ t% M* k; s
( K1 e1 d% d' b; a0 u I% C' u% P6 P- TIM_TimeBaseStructure.TIM_Period = 599;' N* g4 T: a: B; D& B2 t
- 7 ?0 L. c8 A$ v" c: \7 M
- TIM_TimeBaseStructure.TIM_Prescaler = 0;
& c$ |6 T3 r( d( w0 t5 M7 e& H/ u - # U9 Y8 g+ R: C1 s9 ~! o
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;& u3 } y% N: ^
- ; M5 ?5 m g0 \/ o5 C7 Z
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
& O$ k& F2 p5 k) N" v% u
! p( f1 }: s: w/ S- + A" f [8 q: G6 n" b/ E$ G
) @4 J" ^% ]& H- R l+ x- |- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
- c C1 W4 N( w5 Z- o7 M( v9 P - 9 I4 @7 c3 s) H( P9 W+ ?
- . O* r( L" V2 U+ [( ?( p) C
8 z0 E) m8 R% s! L3 r$ Q- TIM_ClearFlag(TIM3, TIM_FLAG_Update);
6 C5 I$ z0 N2 ~* F: Z5 r
+ ]$ T0 o! m+ Q! T) g* p9 i- 2 ^, K5 K( `1 j$ d5 [
- 2 A0 \! s1 ?1 R9 l" z- U( j
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
' S6 q, D4 }$ q3 E6 ]% Z* L0 t0 b
m* o' D# M% }' c# Q/ X4 l5 G
% F' ~+ w1 O6 M
; @" c1 A M& w& }* n/ v- TIM_Cmd(TIM3, ENABLE);
: N* \# R8 p4 C/ a9 l' R
: |) n0 p2 U# R3 G* V0 U- }
复制代码
) _- B/ w( w/ t
* S l% O6 o) @/ `30MHz APB1时钟1ms定时中断。
3 L% i, B9 \) [, T
/ w9 a9 p, n5 }& m7 ], d- void TIM_Configuration(void)
7 w0 j! t: T4 U2 ~# W - 5 @4 g! E% Z* k: E6 d6 f
- {7 t- M- I5 ?: f" x1 Q' y
- 6 o. q( C7 }$ ^! }: V C
- NVIC_InitTypeDef NVIC_InitStructure1;0 y; r7 s6 @9 ^! p( O" }- E5 q' f
' s! f1 s U' b+ p r- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;% d% i6 k$ ]5 R( @+ [4 v2 V* h
- # l6 j& a( G$ L: B; r
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);. h# `# q# t& _: ^) W9 I
/ j# F! J( V) m ~$ z- . D( c" b+ q7 ^4 b9 }
6 y% `* N# j; l6 F" {0 X6 X- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
: q# i& I6 c9 Q8 ~
; `# u$ V2 G$ A1 H" U( I7 `9 h- NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;
, _# ?0 g# t( o; q; n7 i: i
' T0 z) o; l/ ~3 D- I- NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0;
7 t- r6 p. t, m! w - * S, x; Z1 G/ f! J
- NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;
& M0 ?- j+ W9 n% z8 Y5 p - : y8 k5 t& u8 h6 L
- NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;7 |1 p0 v0 e4 R0 G4 ^$ O% L( q: L. d
+ N' }4 q# j' ?- NVIC_Init(&NVIC_InitStructure1);6 H4 @, u& g. H% X
6 A' k9 t+ h7 J' R- / S, W4 y2 x5 r* i1 v" i3 [
- - Y2 L2 q0 _4 K6 j( s0 K+ W2 b8 S3 a
- TIM_DeInit(TIM3);
* M1 E* @/ N! D3 V$ C - ^! O. x+ U8 J, x, f& P
- TIM_TimeBaseStructure.TIM_Period = (60000-1);% d# q# g+ V4 s
- 5 }/ O$ {5 F- M+ h& _, ? Z1 {
- TIM_TimeBaseStructure.TIM_Prescaler = 0;3 L0 F+ t# n/ O( o% a& D, y
- % {2 F5 \5 M% w+ F1 U* ^- [, G. m
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;# `" h$ a$ @8 o p6 X. c
; Y. _+ r3 F, K# X+ J# _- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
, a4 l5 P7 T5 ~) O3 J - * x7 X- U! R3 v- k) [0 d
- ) Q9 q6 @6 v& `4 Q' f! i
- $ V8 ^$ b9 D4 G3 F# N& r# e
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
7 P6 i+ m5 l6 [8 D. \ _9 ^ - ! I$ T" Q. Z6 L3 u
/ D! E4 n# @0 V5 p
' j0 o7 s* R5 j7 Z% D6 b- TIM_ClearFlag(TIM3, TIM_FLAG_Update);$ f1 _8 r: u6 `
$ J2 Z/ `1 Z4 i4 g( k5 q" o3 L- w- % i2 u( L! @# \* p1 J- T
- . [5 @- U6 q; p3 u$ P8 R) U
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
4 A) g# n$ M0 O, @% J+ E - & V; K2 f" k0 }6 Q: J- ^
+ p m) ~, b: P) p0 N- # q6 a ?* p: K) g
- TIM_Cmd(TIM3, ENABLE);
' i6 Y7 j! ~+ p8 ^
+ D1 n, m+ @2 b- {6 K. C- }7 l& a' d+ H5 t% Q
& `: A- I% J2 ^
复制代码 1 j. P% G/ d: b$ b" d4 k! c
|