定时器计数值的确定。
, g3 U7 l4 B1 x2 }7 u
3 N/ l' H2 B3 \. ]0 Z6 C: u- A TIMER的时钟不是直接来源于APB1或者APB2,而是来自经过APB1或者APB2一个倍频器后的时钟。当APBx的预分频数为1时,这个倍频器不起作用,此时定时器的时钟频率等于APBx的频率;当APBx倍频数为其他数值时(即预分频数位2,4,8,16时),这个倍频数起作用,定时器时钟为APBx的两倍。例如AHB=60MHz,APB1为AHB的2分频,即为30MHz,则挂载在APB1下的时钟的频率为60MHz(2倍频)。% _: S6 d- `6 k0 e" D8 _3 R" g
# [" d2 e( f' [& p: j
2 w* l* E4 F6 A, m
$ F) M0 }8 n" h& h& Z! a( W% p各个功能定时器的比较表。
! u" l/ [4 H7 \1 l* \# |6 h1 n
, l- y% y1 ~* G! NTimer分布0 W# F" V1 }% s* Q% n, G
4 Y" S$ ?8 T! e: O1 @
, u+ y5 ]7 P6 B! {/ v3 s3 }
8 P& [- n1 F' n3 t1 w- L
/ ~$ L K) n' A' ?5 @8 g B
. j6 [7 }) z5 z( F/ u7 f4 F6 Z9 g# j* x' b6 C
, g1 E) m7 u7 t7 \% P$ d& Q% p) w0 z' I0 N, U2 z8 g% s" s
0 n K) Y2 B' W+ T; Q; `
% w7 K0 ~: o5 u1 Z9 k
1 i0 ^9 _4 }) x' K
systemtick的时钟直接来源于AHB,而且是24位的定时时钟,一般常用在实时操作系统中。定时非常准确。以下是systemtick的配置函数,由专门的中断void SysTick_Handler(void)。3 d# A1 {! U$ |- B% \- m5 [& }
4 A1 [/ O- \! {! Z/**# a5 {( ^ ~' D8 G1 @
) g& ^. R' q1 b& G$ _8 r% D, k4 W5 T8 x
* @brief SysTick时钟配置。. G* ?: j& E3 n$ V) I- u5 T
* L" `& u" i! z1 } e: F7 ^ * @note 调用的是系统中的配置函数,将其函数名改掉而已,便于统一管理。) }: z, }0 m, Y, K9 m6 o3 m( h4 T c
0 d$ E/ d% ~ ^& ?. m; N+ v/ H( z) Z
* 只需要在该配置中加入计数值即可实现任意时间的定时配置,包括1us。
/ L" |! ~# D0 N1 B$ |) ~8 Q% P* q
7 u0 S" N$ O: h E9 e+ U [ * <h2><center>需要结合中断函数。
% T5 ^( U. _. _9 {4 ~
5 }! l" P, C5 s# T * void SysTick_Handler(void){···}</center></h2>
3 \: _0 K& [$ R3 R: C1 {' c* v- V8 P
* @param ticks : 计数值。该计数值可通过以下公式求得:AHB_Clk*需要定时值,% @( \8 j) N, A1 Q
9 ]0 c9 A2 S4 g0 Q * 例如需要定时1ms,且60MHz的AHB,则计数值 = 60MHz*1ms = 600000。
$ Y' Q, z$ p! q( a" P
& D9 \) ~7 V$ a! d# O; O- { * @retval 返回配置是否成功标志。
. H6 f1 `5 G: d" T ~% Y. a* f# O" J+ z
*/5 `) L5 D5 p4 z. G9 I# {0 O u/ r
; ], b7 X1 H% @9 }/ Z60MHz AHB1时钟systemtick定时中断。9 w) R$ E0 J% H* Y6 }, N t
$ B9 `3 M% n6 @2 w A+ a$ t- uint32_t BSP_CLK_SysTick_Config(uint32_t ticks) o! E0 Q6 ^8 R7 E, s3 L
. N9 h8 Y9 M% w" }; a9 y# \8 b4 |" q- {
% v8 ~! K P/ |" ]+ Q/ j4 N
0 Z9 e1 U5 u- ~# j* _4 p; u- if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
+ T5 S7 I3 \+ t6 h/ E/ P - b( h& y. O# l3 @* N
- ! C) q. e& K( b% k8 s
- B" {, Y8 Y0 t" L9 R" o- SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */4 P! H5 S, L1 }( @& N
- 8 J$ b z- e% H5 W+ S _
- NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */9 h6 c0 C# U5 Q! T- c" C6 H$ a& ]' u
- 4 g5 Z9 p; ]' m/ U- v z
- SysTick->VAL = 0; /* Load the SysTick Counter Value */( `" E& t' s1 k/ ]' f# \
- / J# a. \! j1 {/ t( N( p4 c* h
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
7 a3 T2 `+ r+ j, I; H, w1 A
9 L4 K. W- u% s* {- SysTick_CTRL_TICKINT_Msk |/ \$ e" i; J! p6 j0 F9 E
( f* ^3 |& c8 O& i- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
3 ^! a, ]' ~& [) L$ W* N - ~6 K) n$ k' N0 E: v
- return (0); /* Function successful */
! c+ P! I) o) [
. B2 g! R I5 G9 H& _- }
2 E: V; M! G3 H: ^# W( C
5 \1 \1 A# R y$ g/ b0 X
复制代码 ' {: ~' ?% m5 @5 G( I: B
30MHz APB1时钟10us定时中断。
9 p7 e# J1 Z6 S6 w, Z* g
, U; _4 l( |; A' `# s- void TIM_Configuration(void)
# c) ?. V N! N0 e2 @2 ^ - . n' I) i0 z6 e, l
- {
+ n- [$ N; ^) p; Z# g' ^5 {8 x
0 V8 S$ |: v3 f: b& u8 i- NVIC_InitTypeDef NVIC_InitStructure1;) Q5 T; W& o8 a
& O1 ^ y7 k5 A' d- {) T- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
3 U' ~, ]% l& |7 _. w$ ^. s8 h
' Q6 n) @ s/ m; Z- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);/ T, r' s2 N4 k/ A% U; b
- ( @1 r3 _* o# d
- " A9 J0 w5 R5 P& ?& O+ B% B
8 y* j0 l4 t3 d- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
& g, u" b# q4 `" `2 B - 6 o- D: [* e% w# e8 @% C/ i; @
- NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;
% ]& Q0 ]+ U3 U
1 o: M' ~; S, F8 N- NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0;8 v$ d3 M+ Y! s8 D, K
- 9 H* x( V8 n" x; I9 @
- NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;
' q' G8 ~ n+ W0 f2 c: V7 V - 0 z- ], I! h- F
- NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;
4 w% p& e& u9 ?1 Y
7 g' s o. X7 c/ {7 j$ ~- NVIC_Init(&NVIC_InitStructure1);! F! p) @& x) p+ k
- 7 @# |2 @7 G& M+ j ^- U2 e7 y
- , I4 d' @5 t3 B4 z) r
- . d& t/ u7 u% d, o/ R
- TIM_DeInit(TIM3);
' L# }4 H+ t/ U3 I2 R( E5 x
, r6 x- |5 W/ v5 M( [8 j& j; D- TIM_TimeBaseStructure.TIM_Period = 599;
0 F# Y6 e3 G+ ?8 g; ] - ' r. K+ D6 `: Q+ j
- TIM_TimeBaseStructure.TIM_Prescaler = 0;- p( i* a" s8 \' Q7 ^. J: j
. D* O' W/ ] B" H2 p- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;/ J ^& U/ |% g& u. C
- # ?: t; M2 Y7 ^* \, @8 {; l/ U
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;& P0 S$ ?" K! L7 ?- S" ?
- ) f7 n0 q" N3 ]) \$ M
- $ {! a0 J- e# w( `' `" W5 j5 L
% t+ z( N4 @( Q* t5 @( }7 E- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);) G3 j% Y2 U/ n2 [& t, B
- 3 {! w- j0 S+ u! D
3 L6 ]: K+ J0 |2 M. C: _) Z% x; I
9 T. m8 s8 G/ q U- y/ K: R. \4 @# _- TIM_ClearFlag(TIM3, TIM_FLAG_Update);4 l/ V( A X! B1 @
4 c1 B) A! \% x
- _4 Q* a- T, W8 s" M [- 0 ~) Z y4 `) `$ \* Z* A/ G5 a
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);# z& z/ x5 G& l# c, [
+ F* i/ |3 Z: X- 2 i, ~2 j2 Q9 P4 B4 B6 U
! [* t7 D1 e4 M' w% W1 \9 R- TIM_Cmd(TIM3, ENABLE);9 Q/ h7 s- I' s6 I5 |# c9 v
8 z) M0 k+ A/ p4 j* M- }
复制代码 * n. I$ \5 c5 i/ Q3 E- M
. t) P3 T4 g5 a) s: v8 K
30MHz APB1时钟1ms定时中断。
( H" i1 e0 u- `4 W9 y
3 f% Q( N& ?6 U- void TIM_Configuration(void)! A H+ q8 e4 ]# y
/ e7 L$ G! a2 t, F, T- {
& X) T7 e7 G: p) z% S - + D$ E4 G: ]7 X; R1 Y: g
- NVIC_InitTypeDef NVIC_InitStructure1;
2 Q T& ~9 c1 ^6 K, p) ]7 Z. b* @) B) ?
0 h( x( ^, z6 a# U& A- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
% M2 X# `& ]& a* r: N - 4 S: N# t6 P' l( W
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);% _9 [/ c$ k5 p
9 ~4 {) ]1 b. k7 C2 k
; D* ~: Z' V; g# x- ' `' ^9 }( k* k& c. N
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); Z" [ O( b4 P/ F" u5 ?# K* w
- % @7 k$ h6 J, Z! Q% ~' J1 `
- NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;
7 |! v$ `' o* y+ m+ F; [8 ?
/ ? i& B2 `1 t; y" b- NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0;& A. u( o5 T4 m" D2 v
- q: m( U& }& L4 M1 l
- NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;
5 U: c! m; a9 n. \3 V
8 o$ b7 _9 S7 A4 L* M. k- NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;2 t4 i5 H4 A- Q4 d5 F
- A% k! F: B9 T5 H; t3 X% T
- NVIC_Init(&NVIC_InitStructure1);5 | m/ `- V! U- Q
- 9 k6 c% T) }2 u! |1 S( e7 \
- 1 `. |! e; g7 }* K7 ?
. a$ |$ \- _. C2 t0 m2 |- TIM_DeInit(TIM3);
% L/ s# n) b/ q
# C6 S ?6 N$ K- l( f- TIM_TimeBaseStructure.TIM_Period = (60000-1);( C2 k/ P/ |$ p0 U4 a
- 6 O* M r5 D t$ Q: K
- TIM_TimeBaseStructure.TIM_Prescaler = 0;
8 l U1 U( K4 i, e8 B1 u
C+ [5 N5 \5 x- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;! h' U. o6 h, ^8 i/ A- q3 z
- ( W1 s- K( y- `; S8 R
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
7 ~5 q {+ Z7 W: A/ n - 7 Q. V! N) [: i$ ^. n
- : Y& P: ], r: D6 [7 V- \7 ~/ n
- ' n' K$ R) q; X
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);9 i: B6 F0 v |3 ]- q
- % _4 c7 G$ ~: e+ m
; _ K2 w* @" H
+ I7 U' V, g8 d, F: @2 |- TIM_ClearFlag(TIM3, TIM_FLAG_Update);$ K$ ~8 ~8 H* j9 g# }5 E
- : H# g# {: {1 _ t( `0 r
9 i9 ^) O+ B# }! ~7 ^+ m- p- 3 i- Y8 ~3 x1 j c
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);/ \9 Z) t( W% a/ c/ L6 o/ e4 Q1 k: \
- : p) |+ }( L0 }7 U* H" o
4 a( ^# i" r7 ?' A$ n$ K7 k
/ o) N4 K/ Q, E- TIM_Cmd(TIM3, ENABLE);
6 _$ E2 Y0 h* h @: g8 O8 Y) }6 J - 5 ~2 q: @/ \5 t$ b& ^5 f8 e5 l- o
- }7 m: r' W; S0 D
% i: w8 C) X, B, p
复制代码
l( G/ h% T4 Q% Y+ K$ p# c |