定时器计数值的确定。% P/ w# z7 m5 Z! a, b4 j
9 W; m$ ], K) k, x TIMER的时钟不是直接来源于APB1或者APB2,而是来自经过APB1或者APB2一个倍频器后的时钟。当APBx的预分频数为1时,这个倍频器不起作用,此时定时器的时钟频率等于APBx的频率;当APBx倍频数为其他数值时(即预分频数位2,4,8,16时),这个倍频数起作用,定时器时钟为APBx的两倍。例如AHB=60MHz,APB1为AHB的2分频,即为30MHz,则挂载在APB1下的时钟的频率为60MHz(2倍频)。
0 K% Q6 |3 w/ s% X0 Q( q9 W/ p& G. \& G$ U1 d4 Q: i
/ @2 F" S$ e" g- u) |
: X7 d% d7 p/ c各个功能定时器的比较表。% S; K- e: w5 o2 M. c% i. z
/ O( M5 F% |' C9 |Timer分布
3 Q/ k0 v2 W/ s! W" Q/ N
5 a8 U9 ^5 ^7 ^$ F( V$ \4 h3 S& M2 \& m s3 q) H! [: ]& F
' i- g7 y0 l7 ?( j6 L! l {. T
* ^9 d9 T) G0 w/ Z) Y! w
" v4 |. S* M* j/ y/ x3 @+ D) A+ V; v! d: V8 y9 U
4 E( Q8 c8 A" ]/ N1 D
. ]4 B+ v* w% k& n' l" F( v8 ^3 F8 q
) r& a& s+ \: Y2 K. Q; W$ B
5 G! o' `9 T) i& |% H, a$ @5 E
systemtick的时钟直接来源于AHB,而且是24位的定时时钟,一般常用在实时操作系统中。定时非常准确。以下是systemtick的配置函数,由专门的中断void SysTick_Handler(void)。
% ]( i% v& O6 Q8 E$ \; o7 b- r
: g1 [3 i" p! g2 c8 h: N2 W J( n/**
0 Q' E# s8 {0 N4 P2 ]& d+ \
' ~+ M- L7 i" j' Y * @brief SysTick时钟配置。
) z u9 s$ i2 E9 q# Q! q% h" I5 p
4 m6 @3 ~9 Y0 E * @note 调用的是系统中的配置函数,将其函数名改掉而已,便于统一管理。0 F& b# {% o; F# U& d
$ |* R+ F$ @; A) }# c * 只需要在该配置中加入计数值即可实现任意时间的定时配置,包括1us。+ S( R) a4 L3 }' @2 ~
" g. }. g) ?: b% b * <h2><center>需要结合中断函数。
* G: X# o# J2 U- g p# C6 O: L1 N5 Q# @$ _5 T' Z. p
* void SysTick_Handler(void){···}</center></h2>, W4 d: _3 v1 o' u- |6 Z; l
6 @1 C+ G7 y5 Z6 {' W- w9 K
* @param ticks : 计数值。该计数值可通过以下公式求得:AHB_Clk*需要定时值,
+ G9 n1 H* `! T
% y9 y' s0 l* @5 e * 例如需要定时1ms,且60MHz的AHB,则计数值 = 60MHz*1ms = 600000。
# N# b5 Q2 d4 ?% ~3 o1 k% ?3 b+ D. y3 \# ?
* @retval 返回配置是否成功标志。
6 T8 ]! Y! m7 E* S: o
C2 ?$ U3 Q' L, X6 ?) F */. {! ]+ l" ]) I3 o& x H6 i
0 y0 V; u" V2 y2 R: n
60MHz AHB1时钟systemtick定时中断。
" G6 \& y; {& ^. S) R: p" ]+ F7 s& J: i* H3 ]8 t$ u; X, G, [: F
- uint32_t BSP_CLK_SysTick_Config(uint32_t ticks)
2 U; o1 ^" m- M/ l" \8 b! j6 X( I
* d8 P# L! I- U. t ?- {
2 @; q" q, Q4 R: Q5 I% q2 n" F0 n
7 x% I) q+ Q) p; L$ z- if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
" |& {5 H m) [( n
5 ^$ C( X1 ^' G+ Q& C5 K- ! }5 l; ]) t z- d
/ l: |: ?! n- |7 A5 {6 q4 Z0 h- SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */& I2 B7 W0 j' Z3 g! c
- 2 L" U6 V% _3 l, X
- NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */- m- J( ?# Y* _6 q; i) Z
- / T$ A$ m0 g4 @' }/ s
- SysTick->VAL = 0; /* Load the SysTick Counter Value *// B8 @& I" k: ?* m6 o" @( s8 u
: i, Y. r. x. r% r, J- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |$ o; \! O1 W5 ]; M; l$ \4 ~' m
8 b2 X5 }6 |/ E+ c* Q- SysTick_CTRL_TICKINT_Msk |2 Z( O" O6 `8 F
- 0 [; I) j+ l. Z% S# {5 ]& @
- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
. Q H' h/ A" p4 z1 v, O0 { - & }, r {4 b: I
- return (0); /* Function successful */
+ z9 \3 r _" z3 X, t# E2 h
1 Z( x0 H! J) b9 ]5 ?8 E, `8 Y$ X- }
* h: z1 V: P0 { - 8 R; I0 N) ~7 I2 L
复制代码
" U4 m- D" H c8 G# b7 M' N# h. g6 g7 a30MHz APB1时钟10us定时中断。8 a6 a0 p! `4 p
2 |3 [+ Z% o$ G- void TIM_Configuration(void)/ I% a. p5 E P3 _3 e' V" p0 H
$ f- o, H, o s( x0 N% W- {
& m% W" y; W0 M) g3 ]1 w - {$ ^( ^* S9 }" Y2 G
- NVIC_InitTypeDef NVIC_InitStructure1;; e7 e( r3 ?3 |4 G1 ~1 ~' ~/ g
- 9 b. u, |9 @! C2 t. W: q
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;! A z( P+ n. W1 C0 L3 p
- ! c4 y! l: v8 Q |+ B2 ~0 d: m
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
8 `+ K# r2 F! ~, y' Q+ D1 `+ O5 j - " }% v- Q2 `2 K( ^& y, {: l
- 8 `! ]9 S4 B' p
- 2 `! ~3 N6 m: b9 U" M
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);" K: ~, Y% S) k, a% N+ y
- + E; M4 F$ y0 |
- NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;! D* A9 L3 j( b! F" c5 e2 F
- * F P; a! H( Q! V0 h
- NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0;7 }" |8 K( J* L; n! |4 x
- z6 D+ @% X$ x
- NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;
) h3 u, H) @& L7 M* l2 a - / e# o: s1 b1 q
- NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;
4 ]: ^; L3 [; ~5 D. D4 d7 n+ {% G$ T
% d. K, U7 O- ~4 x# F- e- NVIC_Init(&NVIC_InitStructure1);
8 X+ q3 f) p% n7 |5 w- S - . a' S9 k+ {5 M$ s+ r
8 r) q$ p6 F, l( ]; r
6 e( O6 n1 F8 n c- TIM_DeInit(TIM3);" ^- i! C! f% f/ C
3 P3 Y! W- |+ w& w' ^ _0 v- TIM_TimeBaseStructure.TIM_Period = 599;
) N5 @ D4 H$ G
! B- a2 D8 T) n' r- Y, ]- TIM_TimeBaseStructure.TIM_Prescaler = 0;
, m) j; U4 I8 }# J+ h
' x0 N- R- y2 u7 Z+ B$ B/ B- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;6 ^ h" l# m) U" Y$ \5 t9 B' G
- 2 g- q- {* ~5 |
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
# z( K) ~4 p$ V) _+ K - 6 f1 f2 m: N! d$ \& ^4 [( ^
" n+ H. A% A# x) d& v- $ P$ d# `; {, u2 [8 |" E
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
' f( \* J' ~% \, r; |
1 E9 C1 x( p. I, ]3 u
4 `& ~9 l, L y; r" J% i
% ?1 ^4 p" S8 y/ @- TIM_ClearFlag(TIM3, TIM_FLAG_Update);7 l) `- \. A4 F6 o N8 p
; s5 h: l# Z7 n$ `3 e5 s7 Y$ X" H- ) t8 t# m, m5 A/ u
- 0 a# ]3 g# R, J& x
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);0 s+ J8 ]) F- f% s5 x: y T
6 N- x E5 y$ ?, j- " e/ M, |" i! e9 M; P
- ) f+ S% X6 J! t' u& H: b: T
- TIM_Cmd(TIM3, ENABLE);
& Z" C% L q; ?* c# y - , A2 M2 \# }; {; K( h8 P! ]2 {
- }
复制代码 " g$ U$ n2 P5 e. f8 z
# x0 Q! r- n+ e. p) `2 K
30MHz APB1时钟1ms定时中断。
& v" B" i$ J! g7 B3 L7 ~- |6 V# L! c# ]# {
- void TIM_Configuration(void)2 h: t7 W: a9 c& w, A; H
- 6 P0 z" r3 @+ x8 }5 c
- {# I# U) X+ B& Q k8 N4 q9 p5 D
- 7 F5 a1 G) I5 X
- NVIC_InitTypeDef NVIC_InitStructure1;
; e. h; Q3 r8 n7 I - 7 b8 a# Y% M$ A! S! R
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;3 k/ l) P: J8 K3 ?2 {
- / `. b/ Q, [3 F* j$ o- n o
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
( U3 d l1 C2 |
4 [+ r0 p4 x- e* m+ [# R- + o6 @: Z( C/ ^ Q
- , p* c! ^/ L& k/ j
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
2 ?3 V5 \5 U, J; T2 ^' a - 3 l6 P% M, U. T7 U8 s) P8 A' G& Q
- NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;
O% F0 Z; `0 M8 E+ {+ k4 P - 0 ?- E" X4 @+ c* O/ @- e3 ]! Z
- NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0;
3 x, |/ u" Z; H5 I3 \( g$ A& B
2 ^. e; W0 y6 \- NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;
9 c V- Z/ X9 e3 O6 J% b - 2 W4 E' l: K5 \3 Z
- NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;
. O' U2 J3 g( E - * P7 K- b6 E: S1 F7 C
- NVIC_Init(&NVIC_InitStructure1);
, X8 z9 `" {- O% c0 y; j2 y - ! z+ j) D: ~6 X# T, m) f9 P: [3 k9 S
1 \" z6 l. Z0 s' p0 n- % g7 K* Y2 v1 _2 v% B$ ?3 o
- TIM_DeInit(TIM3);
6 @9 e6 `; J# s- M; W8 `6 k - / _* U; g- X3 p. e+ Q3 R9 W
- TIM_TimeBaseStructure.TIM_Period = (60000-1);
& g! Z5 _ @% C' {
6 S! K* t& L- B' v- TIM_TimeBaseStructure.TIM_Prescaler = 0;
+ }9 M6 S" o Z( G8 n - " N" H' G6 A) J7 J' ?! R
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;3 l7 L/ o3 ~( E! T B0 q7 C
Z; ^% C) ?5 f' O& ?; V# A- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;8 H+ u# h! e* ^
$ }6 @( S1 ~% m
. G$ v' U: l% u3 g& ]& h
5 Y5 v; T6 R8 d k) L- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);: z8 `" h& C9 d c% w! j
3 W r. n9 o& ~ p- * a0 r. z/ g# Y
- * T( o* S/ B! x ]0 d; v
- TIM_ClearFlag(TIM3, TIM_FLAG_Update);
$ J' H- q4 U9 H- U9 g$ H$ M1 { - $ E, W% }8 Q6 v3 x" g
- ' \5 l$ w" P( q
1 k& e% |/ N2 H7 @% }- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
) |; b+ Y( U# I# T8 w - : R( e5 T& f$ T9 T
- , u6 w$ T* R7 ?
- K4 y2 s. }, R( D" X+ j3 S
- TIM_Cmd(TIM3, ENABLE);
4 L7 ~2 F1 O! f3 i, V1 s3 V& I - 2 K" v. }0 v( N# Z
- }: p G& {% G9 x" k
- 2 F$ U7 C, s- ]6 n; }2 v5 w
复制代码 6 i9 U6 o2 x9 \$ I3 r
|