基础了解7 Q' v* c& K2 H N( u$ `
时钟选择计数器时钟可由下列时钟源提供:
6 L% H* t$ p* v$ P0 Q3 d' d) \
( ?& |3 R* z, l; ]$ E/ M
, w) I7 a& [9 f0 V) h● 内部时钟(CK_INT)
8 r" a4 D- c z& I9 s" w● 外部时钟模式1:外部输入脚(TIx)
+ Z, m4 F3 B# [. p● 外部时钟模式2:外部触发输入(ETR)
+ s; s |8 W- N' Z) g● 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器3 u; A) h+ y* W" q9 d6 }, M9 |
t, E1 ?# Z3 r8 f* I; A, j& F
/ M" f) X2 |6 t+ \4 R) A: A
在平常使用中我们系统复位 000 默认使用内部时钟源5 Z+ y2 C7 X8 m* }) }
3 ^ p- g2 |) |: r# z) _. f
# B: ^; E7 X5 M; H+ v& R( i
内部时钟源& `' @/ {! Q5 v" M" G
从时钟选择框图中可以看到,内部时钟源(CK_INT)来自RCC的TIMx_CLK,即定时器本身的驱动时钟。6 x: K b' Y% y
M- l4 z6 t8 a f3 ~: t
) Q1 M* |! k2 w2 r 当禁止从模式控制器(TIMx_SMCR寄存器的SMS=000),则预分频的时钟源CK_PSC由内部时钟源(CK_INT)驱动。定时器的实际控制位为CEN位、DIR位和UG位,并且只能被软件修改(UG位仍被自动清除)。只要CEN位被置1,预分频器的时钟CK_PSC就由内部时钟CK_INT提供。
4 |2 z9 c& x$ ]4 o& }# }6 g5 E8 ~* V7 v6 d1 \- s
" Z( `. d# |: R% y. H$ Y
通用定时器的内部时钟来源于APB1总线时钟,但是通用定时器的内部时钟是根据APB1总线时钟是否分频来决定的,如果APB1总线时钟预分频系数为1,则通用定时器的内部时钟就是APB1总线时钟;但是如果APB1总线时钟的分频系数为2,则通用定时器的内部时钟就是APB1总线时钟的2倍。% t4 l' z/ P2 L( z: F ?
% v: K2 B, z$ M K; D
, X4 E1 H$ z. Z/ j, [: Q 下图显示了控制电路和向上计数器在一般模式下,不带预分频器时(分频系数为0)的操作。- v5 X: U% t n6 [& {+ R# F
% X; b2 ^: B7 U" H' v0 J' t9 k
如图所示,只有当CEN位被置位高电平的时候,预分频器的时钟CK_PSC和计数器的时钟CK_CNT才开始工作。
2 C. P& M. R2 t0 K2 Y3 K+ C. ?
9 j0 U* l6 p8 e5 d' B! {+ S7 g3 ?2 d- ^* M+ P6 |* v# ?
外部时钟源1( x% I/ Y) o. q% A, c
3 R1 ~3 H( S; O& @$ {8 M2 P+ [
来自定时器自身输入通道1或通道2的输入信号,经过极性选择和滤波以后生成的触发信号,连接到从模式控制器,进而控制计数器的工作;" B, ~: b \, N& u h- p
* e' Z9 Q9 [) Q/ S, \6 U( l/ _4 ~) |& w
( S& {/ u* _$ e- q, ]4 l- p来自通道1的输入信号经过上升沿、下降沿双沿检测而生成的脉冲信号进行逻辑相或以后的信号就是TI1F_ED信号,即TI1F_ED双沿脉冲信号。$ c5 Q( J; c+ {6 @$ O2 e- \& e
5 U3 X; D" S: q5 t
$ l [( a) _0 @相关函数* d$ B K1 t! R. c% x
TIM_TIxExternalClockConfig(TIM2, TIM_TS_TI1FP1,TIM_ICPolarity_Rising, 0);
q- A( m) S/ ~$ w7 _//设置 TIMx 触发为外部时钟(从四个通道引脚引入)! |( O6 e" l h6 {6 j' |9 P4 _
//触发源选择:
4 s% l+ P$ n) R7 e//TIM_TIxExternalCLK1Source_TI1ED: 双边沿的Timer Input 1/ F0 t! T: r$ ~3 y" f# @
//TIM_TIxExternalCLK1Source_TI1: 滤波后的Timer Input 1" U) F' d6 h4 D* k6 F8 {
//TIM_TIxExternalCLK1Source_TI2: 滤波后Timer Input 2
$ P& |# ]6 d. _1 _//设置输入捕获的边沿:1 r& M+ e0 a( A
//TIM_ICPolarity_Rising
$ G8 ?) e+ s( f' t' i, E//TIM_ICPolarity_Falling' K# ~0 O5 _* U
5 e8 W7 Y. Z6 T O* b* F# f+ g% N! v+ U& Y0 z
//TIM_ICPolarity_BothEdge
- t+ d5 u/ ~# q' B
8 G/ L% v) Y* i+ T+ S1 ~' }: Q+ g% @& A( D, G
//设置滤波设置:! a* |' a5 [' M* B8 z1 |7 y
//必须在0x0与0xF之间
1 ^' P9 f5 w9 W' H8 r2 Y) y* i0 x+ W' {7 h+ d+ g( `
; w2 B; W# U# d6 G$ P- U8 @( A6 G1 i代码示例
$ u: q5 t9 l, Y7 N时钟源对频率进行计数9 l0 w4 x- J; y u" i/ ?+ X: ~
- #include "timer.h"/ D+ J4 T( D0 Q7 [
- #include "led.h"
, `" S- i: n4 M+ y; ]! n; j - // - l( H* \% u7 L# q! [8 {
- //将PB5与tim2-ch1的pa0短接. ^& J0 S& @1 p5 A. E0 | w
- pb5为时钟源对频率进行计数) ^2 G! { v1 y3 E# Z; f
- . P9 T3 Y6 B8 I2 H
- void TIM2_Int_Init( u16 arr,u16 psc ){4 I1 M- {* B1 j9 [7 M: ^9 G/ [
, H7 M$ _# [/ O3 |7 |1 b; P2 a- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;) C1 } A" b0 V$ {) q
- NVIC_InitTypeDef NVIC_InitStructure;9 D6 F% n8 _2 q5 D" L/ M
- GPIO_InitTypeDef GPIO_InitStructure;) m5 Y8 s8 Z7 E/ l+ b
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);- {; q4 t m. ~; Z0 }$ H
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
4 |8 g! _( R; u2 I2 _( ]& x- r - GPIO_InitStructure.GPIO_Mode =
& W1 @9 p$ k% a - GPIO_Mode_IN_FLOATING;
1 h$ e# A5 l+ L; R2 _ - GPIO_Init(GPIOA, &GPIO_InitStructure); ' K2 ]2 U& i; A- a1 t
6 A# l3 |7 I; v+ P8 A- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
; i/ Z( x+ s. ~ H+ k9 p# c6 J - TIM_DeInit(TIM2);$ W& f* Q% G. K2 T1 J
- TIM_TimeBaseStructure.TIM_Period = arr;
6 B- v$ q" ], c - TIM_TimeBaseStructure.TIM_Prescaler =psc;
/ v" p0 X4 z( ^, U- S" H - TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; C4 D) \9 U* `, G6 t/ ]
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; % _0 s/ {! z7 I2 \, L
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
5 L0 w. B- h; y K) k) D
$ d8 T- P+ ]2 i& ]0 o- TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); + s5 T! P* d" O9 _
- /*重点*/ 7 x$ x! H) D$ @
- TIM_TIxExternalClockConfig(TIM2,TIM_TIxExternalCLK1Source_TI1,TIM_ICPolarity_Falling,15);//设置输入滤波和边沿检测: c2 _2 H6 p8 |* n1 e3 R
- TIM_Cmd(TIM2, ENABLE); 2 a/ B7 D# ]( q! e! ]8 Q& @$ X
- //7 B, E! t, }! Q
- }* D& @( J- m1 ^( F
( E1 A* a9 r/ g$ n1 H+ n- void TIM3_Int_Init(u16 arr,u16 psc){
6 g/ y* W5 M0 b+ Q! z+ q7 V. \ - " l+ b; T# u* z- F8 Y5 b: R: }# K0 {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; L! J* D V M& c5 Z0 N
- ! L1 h, ]+ J5 @7 `6 v6 m3 Z
- NVIC_InitTypeDef NVIC_InitStructure;
z/ F- B* M, M$ z) y3 G+ N. z
2 p# o% Y1 W3 q- 8 W% O+ P) o5 d- l ]
$ N6 V/ I3 H0 x7 l: ]* W- / p7 G" h3 i, F! D- V! \. B$ B/ L
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); ! r3 u* A; V4 {# P
- TIM_TimeBaseStructure.TIM_Period = arr; # O; N4 j! d8 ^/ u: v( M5 C/ F
- TIM_TimeBaseStructure.TIM_Prescaler = psc; " b; z8 F7 e: }6 c; x+ n
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
9 _: ]8 K" f1 X' E - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; , z2 d" u. b5 Z# y' ]/ p O
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
% m. A! c, G& G2 V7 G& F; a, b) ^0 y3 I
7 N( J* g# i) q$ q1 i+ j- % n. ?/ D1 K; E: c3 s2 A# F7 F
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
4 T+ S. r4 N9 n3 u/ A0 r; A# E - NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; + w3 S6 s/ ?$ h
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 4 t @# Y0 E' U4 @$ T# K0 m9 ^7 S
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; ) F" I( q3 ~: z! z* B. q3 h- q
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; * I$ r7 E* @- s8 _
- NVIC_Init(&NVIC_InitStructure); 3 m0 X2 S9 Z% L5 S4 N2 s
- ; j- T6 K8 I9 P) q! l9 U
- TIM_Cmd(TIM3, ENABLE); 9 w( l$ l7 p0 D5 t, ]) V
- }. k* P; q3 V4 t/ c$ Y- F% B
6 u7 D$ ^$ y8 K! X" q$ A" m- void TIM3_IRQHandler(void){
/ y/ z6 E: x9 S9 X' C - 7 M# Y) |. C* ^ s' S4 Y* ^+ s
- if (TIM_GetITStatus(TIM3, TIM_IT_Update)!=RESET){; X% Q" Q$ S; j0 T2 D6 k1 X
- LED0=!LED0;. Y4 |* q. \/ L5 y% ~; t! Y& W
- }
, h! l r" ]4 Q- d - TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
0 n1 @- w* z2 p! @2 K4 I: o/ D( E" n! z - }
: w* f' R3 P" i( p; W/ E - #include "led.h"
7 C0 J7 ?6 L+ E, _5 N" p) ^4 m2 R) c3 Q - #include "delay.h"
1 A: h2 g2 N8 W6 ~( b6 ~ - #include "key.h"
/ G- A( g- [+ x1 \7 ^/ C5 [2 f - #include "sys.h"
0 D3 `. s/ w/ ~1 t/ t - #include "usart.h"1 g/ K |2 F( E4 p4 L- j0 N
- #include "timer.h"
8 E8 c% g; {' R/ ?' E - : U# f7 m; b4 n! w C/ H
- int main(void)/ G/ Z, X2 T, c+ N7 q$ S
- {+ ` O, ?& t7 \* ~( p7 t
$ c/ v8 r- v% ?: S- delay_init(); //延时函数初始化, N4 ~& t" V \% C5 z$ E) L
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级4 J0 A" C, D& W4 U" e& f" O# j( J
- uart_init(115200); //串口初始化为115200
; c! ?1 u3 T7 k - LED_Init(); //LED端口初始化9 G1 o- [5 h" ~2 c' u& H2 B
- TIM3_Int_Init(4999,7199);//10Khz的计数频率,计数到5000为500ms' F! h. w* g6 V# w5 s4 U+ p
- TIM2_Int_Init(10,0);* x$ c9 Z+ R2 q
- & P+ F4 E& Z- N$ ?2 t8 e! B
-
) \) Q$ a) k% f+ f' G( S& R - while(1)$ W/ A7 ]0 p2 T" F N
- {
5 ?$ Y1 p9 z* E - //LED0=!LED0;' C- U0 [2 {- h5 {. B
- delay_ms(400);
4 o5 g' L8 E0 I) T+ Z( X - printf("Count=%d\n",TIM_GetCounter(TIM2));
0 U& [: J+ E) X8 ]1 q" k5 [% j; a - }
8 |' @( b" Z8 k8 X5 }4 `, u
% |. h" A$ p% i" p- % j1 ~' w5 r) U
- }
复制代码 //TIM_TIxExternalCLK1Source_TI1: 滤波后的Timer Input 1
/ @( k/ Z: u% ^* H//TIM_TIxExternalCLK1Source_TI2: 滤波后Timer Input 2
+ }8 W; X$ j, e1 Q7 `. M
4 H( _+ K% o( q0 {8 O
- i. S, Z, b& d# ]5 ^这两个选项T1是CH1通道 T2经测试CH1与CH2通用
; A6 I. Q7 L9 i' | J' d" W5 {2 ^
9 \0 [/ g! r3 }" A
7 W+ k* m) i. s$ w+ `/ j3 ` p大概是这个异或的原因7 U$ ^5 b) x g$ w# [+ w
. O8 I8 u6 V5 Y3 Z' P外部时钟源模式2
3 a1 n# }% w1 R6 X9 F$ M1 w8 Y3 \1 `' g9 w6 W& H) B6 A
来自于 外部触发脚[ETR脚] 经过极性选择、分频、滤波以后的信号,经过触发输入选择器,连接到从模式控制器。当然分频和滤波不是必需的,可以根据外来信号频率高低及信号干净度来决定。
+ a1 i- L; R0 r* Z& ]& ]: l/ ~' k& l/ y+ Z' d
' J4 l! a- x# r/ t& s
ETR功能较全可以完成T1的工作但仅限于CH1通道,可以经行分频2 l9 k& V9 O @. q5 O) j
; W! C# y5 `0 S7 x* A5 f: R. |( N& q O' G0 ~, K
相关函数6 m( i' Z" ]- d: Z7 }3 P# }! @# k
TIM_ITRxExternalClockConfig(TIM2, TIM_TS_ITR3);8 t( w1 I$ @7 J) B
//设置定时器工作于从模式,时钟源为其他定时器的输出分频.此时钟源无滤波/ l" ^! R2 G- B! B7 a1 r
//TIM_TS_ITR0 TIM内部触发0 TIM1! b. x ?. y- W% u; @! m) y9 k
//TIM_TS_ITR1 TIM内部触发1 TIM2" E5 x- c' H: f1 }( ?/ M
//TIM_TS_ITR2 TIM内部触发2 TIM3$ _$ j5 f7 S" ~( g) _3 j& P- k
//TIM_TS_ITR3 TIM内部触发3 TIM47 R& _/ ~. S- S" L$ B
! ^2 \$ Z: ]; [$ P$ I6 z
* B/ ^: b9 H* j8 C! O TIM_TS_TI1F_ED
4 G) Z/ L3 [5 g% }* z- cTIM_TS_TI1FP1; ?8 @; @8 Q: ?; e( k5 d4 m8 N* @
TIM_TS_TI2FP2! j9 C( s+ f9 }
TIM_TS_ETRF
7 V+ }5 _) `) P6 U9 P8 h* ]) V& m5 v. ~7 K5 L
9 R# C# R: P4 G9 u V$ F6 s9 k, PTIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_DIV2,TIM_ExtTRGPolarity_NonInverted, 0x0);' c' d4 {1 H: g1 _+ X* k# ]: D
//外部时钟模式1.需要设置预分频,以及外部触发极性:滤波
( j% Q, x7 [' u6 {2 p( {5 V0 t//TIM_ExtTRGPolarity_Inverted TIM外部触发极性翻转: 低电平或下降沿有效 //TIM_ExtTRGPolarity_NonInverted TIM外部触发极性非翻转:高电平或上升沿有效
) i1 L& V# H! Y* k" b
P/ w- \9 E' }5 [- l" H9 q; q1 y6 _4 T" M9 C2 g+ Q2 |, x
代码示例1 K: X0 {# r3 u& ~' x7 ]2 k' }
由第一个示例更改,功能一致main不变& s0 O* X2 n7 W1 N
+ h# Q% \3 p1 D& Q4 J
- void TIM2_Int_Init( u16 arr,u16 psc ){& w* h: e- A( o5 P, E4 K& }
2 r2 g7 R$ n* G% k* ]2 B* c- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
& @. `$ R8 d# ]3 T# E0 M - NVIC_InitTypeDef NVIC_InitStructure;( l0 w2 d$ Q. ^6 [ n6 [0 ?
- GPIO_InitTypeDef GPIO_InitStructure;0 T4 W, ?- b9 Y8 D
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); * G- A' y& m) A
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
- h7 x5 N4 ~6 I5 a - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; * z6 s+ ^" I: ?$ G1 u" l- z( B: f
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- B+ c* K, Z5 B1 ~ - GPIO_Init(GPIOA, &GPIO_InitStructure); 9 x( i% g; ]6 [# z' v. r
-
% e5 {' `, X1 ` - TIM_DeInit(TIM2);
5 B/ P( {, z& @+ e - TIM_TimeBaseStructure.TIM_Period = arr;
8 o% w. n2 T' F! H/ L - TIM_TimeBaseStructure.TIM_Prescaler =psc; ! v, N/ K( Y6 O7 i6 l G _
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
7 l0 h5 w8 u# ^# h3 y - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+ D0 K; d3 ~- q! S" P2 f$ w - TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); . N/ U6 r9 s) {' F
# l7 K2 N4 g! f D1 o8 g- TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); - M! G) K- @" U- S3 I4 O/ p5 X
- - N2 a4 a% F) u9 b- N2 }. b
- /*重点*/, T- w- N, T; O M1 z
- TIM_ITRxExternalClockConfig(TIM2,TIM_TS_ITR3);//高级定时器开启
7 Z+ _+ Z+ O" ^0 v+ y- c - TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0)//配置外部时钟2的模式;
Z* Q0 w. C% v# z3 ^) ^( O; E - TIM_SetCounter( TIM2,0 );! |3 j* A3 g' ]5 R8 S
- /7 j! r3 a/ z1 j
-
' s/ ]: P. J9 S& _) ?1 E: |1 S - TIM_Cmd(TIM2, ENABLE);
/ r) i2 v2 g' R- I% }1 c - ' P3 p; L9 u) o% ]9 g
- }
5 e& d! w' q( ^; [$ `; c! j, Q8 b - void TIM2_IRQHandler(void){
9 j2 ^( z. f. a9 t0 Q1 C - # V; `: p! N( [ C4 q P2 F8 P* u& P
- if (TIM_GetITStatus(TIM2, TIM_IT_Update)!= RESET){; ?, }: S3 S% y; A+ J- `5 |* y; O
2 l& A$ x- Y6 L! W- } V. c8 B! ~% V' ^1 v
- TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
' P7 }1 u4 A5 Q# y* h7 q - }
复制代码
. |, h# `# `1 Z( T& e8 q3 J
/ t9 V5 d/ w2 y" m& p |