基础了解7 r( k7 d+ k: q* O/ q( ?
时钟选择计数器时钟可由下列时钟源提供:
) l2 i% G; G: w% A" o! g7 z7 k3 M6 g" B6 G% u, W) L- H
7 r: X/ i7 Y$ s) O$ n● 内部时钟(CK_INT)3 P( c: i" S) w+ p9 S" k) K
● 外部时钟模式1:外部输入脚(TIx)
' X5 j% N1 P- r( j; _● 外部时钟模式2:外部触发输入(ETR)2 u4 f$ Y5 Q w
● 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器( u1 J, Y: w8 A* N- ?
* u: l3 R% @/ d- I1 W4 i/ U c* d% `" O( x: }: q
在平常使用中我们系统复位 000 默认使用内部时钟源7 W7 h) _6 _2 {+ A/ i! G
# a- M$ V9 k1 N( J9 a9 C u# ]
! a- s5 N" p8 s内部时钟源9 j4 h' n" ?0 q6 R
从时钟选择框图中可以看到,内部时钟源(CK_INT)来自RCC的TIMx_CLK,即定时器本身的驱动时钟。
& B" F8 f- t" Y+ |7 T# ^% M1 |) }) T7 P( u
9 A9 U, R! D: W0 i/ F7 F8 D# u. x 当禁止从模式控制器(TIMx_SMCR寄存器的SMS=000),则预分频的时钟源CK_PSC由内部时钟源(CK_INT)驱动。定时器的实际控制位为CEN位、DIR位和UG位,并且只能被软件修改(UG位仍被自动清除)。只要CEN位被置1,预分频器的时钟CK_PSC就由内部时钟CK_INT提供。
7 ?, t+ X% I' m) t- l, b& _. }$ g7 c6 T2 X- `: q% e
! h8 {' I/ _+ Q 通用定时器的内部时钟来源于APB1总线时钟,但是通用定时器的内部时钟是根据APB1总线时钟是否分频来决定的,如果APB1总线时钟预分频系数为1,则通用定时器的内部时钟就是APB1总线时钟;但是如果APB1总线时钟的分频系数为2,则通用定时器的内部时钟就是APB1总线时钟的2倍。
2 L- e4 W3 i# M |5 v2 ]+ D3 n; s. \! ^
: d9 h5 H8 _4 ]+ Z* t
下图显示了控制电路和向上计数器在一般模式下,不带预分频器时(分频系数为0)的操作。
4 P. {( X1 {& x/ V% T# Q. [
2 ^" n$ F/ v6 X% q( M% n 如图所示,只有当CEN位被置位高电平的时候,预分频器的时钟CK_PSC和计数器的时钟CK_CNT才开始工作。3 l. W3 _% w1 p" W+ C
+ V/ t" g( d4 }( e# j& }& j
: i* H) d5 {* n9 Q0 _# c9 i2 f) U外部时钟源1 ? ~( s* r, E9 ~1 c7 [6 N
) F8 H1 p+ j. N* F U- H
来自定时器自身输入通道1或通道2的输入信号,经过极性选择和滤波以后生成的触发信号,连接到从模式控制器,进而控制计数器的工作;7 y n% ]9 f; i; b- G* u$ B
9 |& m- Z' U% g' H+ E7 O
! Y# x4 L0 k( k2 c4 ?1 j) ^来自通道1的输入信号经过上升沿、下降沿双沿检测而生成的脉冲信号进行逻辑相或以后的信号就是TI1F_ED信号,即TI1F_ED双沿脉冲信号。 h6 z, b, N. L
6 F; ^6 r4 B# T% X5 w C
1 @3 N0 {5 }; G- B& r4 z( g+ F相关函数
3 F4 X) j) Z: pTIM_TIxExternalClockConfig(TIM2, TIM_TS_TI1FP1,TIM_ICPolarity_Rising, 0);+ p% B5 s$ ]' u3 b5 _& e
//设置 TIMx 触发为外部时钟(从四个通道引脚引入)5 X& z2 d; d3 L9 Y
//触发源选择:
+ o" @: J+ C- Z- P& q% s* J0 T) j! D//TIM_TIxExternalCLK1Source_TI1ED: 双边沿的Timer Input 1
% e" \: f7 [2 n, J6 Z7 _3 q//TIM_TIxExternalCLK1Source_TI1: 滤波后的Timer Input 17 p+ @ }! J. o) Q* v8 ?
//TIM_TIxExternalCLK1Source_TI2: 滤波后Timer Input 2
+ G$ i: j! f4 m9 y1 B! ~( d, `//设置输入捕获的边沿:
$ ?) { i9 r- i- V( f//TIM_ICPolarity_Rising* n l/ d+ j' \; {1 U0 M% i
//TIM_ICPolarity_Falling6 j. i5 u. R d. i: Z; Z$ L q/ g
9 i Z9 f! l! J" H
' }( w0 b; G, A5 g5 `4 L K//TIM_ICPolarity_BothEdge
) Q7 f! T4 B1 I! j$ L+ @
7 X$ ?' s+ S" t9 H: r! Z
, g, u6 ~* \# ?( E//设置滤波设置:7 M* y% \! A7 D5 n
//必须在0x0与0xF之间
% t4 `7 M3 T$ X j& }% ]) o7 @: u# J/ t3 u' T" @1 ~ N- Y
' c9 }& v5 C! d D代码示例6 Z% b- Q% ?0 D) k$ ^
时钟源对频率进行计数
' r# r# t1 |: ] H, e: q# U' X/ |- #include "timer.h"
8 o; l. q! S( u' O0 [, s+ V# X - #include "led.h"+ y# m F. E& a) V( t' a; ]
- //
+ o- r7 I, p6 C2 m - //将PB5与tim2-ch1的pa0短接 x- j: ?8 \. ]- |* A
- pb5为时钟源对频率进行计数
5 x( O# j# i! b+ t; y. x2 g - ) _- t i& Y0 S1 E
- void TIM2_Int_Init( u16 arr,u16 psc ){
" ^+ U6 o4 H2 F* D
$ B% D5 K1 _! Y9 i( D- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;+ V, T* T( }: v! C$ \
- NVIC_InitTypeDef NVIC_InitStructure;
' N! o9 a, r; M3 s8 q- y - GPIO_InitTypeDef GPIO_InitStructure;) D4 f7 j+ p1 N9 E" I; S
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);6 y2 c: F u. k7 @* i, { d
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
' ?4 X9 i( L# N - GPIO_InitStructure.GPIO_Mode = 0 b8 @! _6 l5 n5 h$ q
- GPIO_Mode_IN_FLOATING; - x# R1 r' Q' o2 w1 U
- GPIO_Init(GPIOA, &GPIO_InitStructure); # t5 O, ~. g1 h. Z
Z' r6 `+ d. p" [5 X! z- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); % a% e' X3 D, q9 M4 h5 E
- TIM_DeInit(TIM2);" |; h* H F8 I
- TIM_TimeBaseStructure.TIM_Period = arr; . J/ ~" E5 Q) j: B! v0 G: c g
- TIM_TimeBaseStructure.TIM_Prescaler =psc;
- z# N5 Y1 v/ ?. z4 b" i - TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
5 S2 Q% K/ P9 t" ] - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; & A/ Z% E$ r) _/ K+ ~" }
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); ; E& ^* F9 z0 o2 I
+ O2 X- ^* v( p- TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE );
6 E6 c4 W$ s- `7 r - /*重点*/ ! J6 Q, I( l4 ^# X' u4 _
- TIM_TIxExternalClockConfig(TIM2,TIM_TIxExternalCLK1Source_TI1,TIM_ICPolarity_Falling,15);//设置输入滤波和边沿检测3 r* R$ d" x6 c
- TIM_Cmd(TIM2, ENABLE);
: \% ` A8 x7 x4 ~' j& s+ l" c - //
( a3 M- E; ~% Z5 J, ?! @# y+ `; u - }, X- ]. i! K/ e Z/ {$ l. P( h9 i
, y/ E) h& S0 _# m) o5 J! T- void TIM3_Int_Init(u16 arr,u16 psc){7 z) d4 V, W& {% W
! @9 v) _; n7 V6 m6 l' P) C- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
6 B" c! p% g* B' }7 v% p
/ |; n9 P4 S" U0 T) A3 Q) H- NVIC_InitTypeDef NVIC_InitStructure;& ~1 s9 D; p/ }
- ; ?+ q. I5 G# P! ?' e
- 0 h, e/ X! z5 r1 z
% |) ~: s$ l; N( Y
1 Q) R& H9 B3 O5 s' Y- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
h# V& K: H1 L* j- L( X - TIM_TimeBaseStructure.TIM_Period = arr;
8 V! X& j" T8 m( b - TIM_TimeBaseStructure.TIM_Prescaler = psc; , E3 S: J! g6 i3 }' J
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; , u) ]& j$ l* ~; Q/ ?
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
* C+ R$ K1 N5 m2 b' T9 l% U! g - TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
t8 v2 `" m5 L2 u) f# } - 4 i5 S1 K/ n4 p5 P5 V5 R6 V
- 1 w9 w% V) \$ |5 ^ j
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); " ~4 m/ _4 o- K+ ^( g
- NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
9 t: D( D( l9 i& U* F - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
, Z$ o* w; \; i1 y: [" \ - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; # }: r- ?* Y( Y X# e1 b b
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; ' d0 C2 n& J& M7 ^/ k
- NVIC_Init(&NVIC_InitStructure); 4 v4 Q6 ~6 k6 ?4 O6 l G) I
- : c( |5 m& U/ p) \4 M1 ?
- TIM_Cmd(TIM3, ENABLE); & N; R' A' t. C: C$ H
- }
9 n3 |4 [7 i8 g - ' G7 v& l6 O5 ]7 d9 X
- void TIM3_IRQHandler(void){
6 Y" F# [- I" b6 s( Y - 1 J2 a, `% O, e1 g
- if (TIM_GetITStatus(TIM3, TIM_IT_Update)!=RESET){: t* Z4 a7 J4 A4 E) k' W
- LED0=!LED0;$ m0 A# w M, J r5 i a5 Y0 z2 d
- }
; h9 P8 A }% B* f1 [8 d- m) j - TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
/ y: Y G- _# }) l7 L - }9 }2 Q0 K2 T {; [- X
- #include "led.h"
; T: p0 x( j9 B! ~% P - #include "delay.h"
# x% z/ s% h+ I# S) @. v - #include "key.h"3 F2 A K, ?' m0 `: J
- #include "sys.h" T4 U5 ~" F. {0 S, G1 e+ K
- #include "usart.h"8 o( N$ }8 Q8 ~) [7 D
- #include "timer.h"
% F% [8 U& W7 ]$ Y$ F; A. C3 S
! F/ W+ n9 C+ f9 q- int main(void)9 P. z* l! `$ m3 V. Q7 I
- {5 u7 @2 [2 g2 p5 v. Z, p6 i, w
- % ]! \1 H# c+ t; J- y5 I
- delay_init(); //延时函数初始化
2 R8 ^% e T4 {- c3 u - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
4 ?+ a, Z3 R6 x9 Z$ K& }. D - uart_init(115200); //串口初始化为115200
5 i& o( o6 K9 k" \; a) g, l - LED_Init(); //LED端口初始化0 q {2 |' u: @; |5 ^. x" t' t$ U5 a
- TIM3_Int_Init(4999,7199);//10Khz的计数频率,计数到5000为500ms
# ^) f( c. U) G& x( D, b& b - TIM2_Int_Init(10,0);
+ ?% a; p( Y S6 r8 u9 u* e
: ~* q: U' ?; m ]4 B. N-
1 O) ]2 b8 m8 K% d - while(1)* J/ @: f5 R! G8 O
- {
/ E. [$ w7 w8 Q; n, [& c) w5 f - //LED0=!LED0;
5 |9 ~1 X! M7 C5 o4 Y2 ^ - delay_ms(400);6 x2 L- O7 k6 i) z5 g. @
- printf("Count=%d\n",TIM_GetCounter(TIM2));
( x/ i5 \$ v* g# b: E% n - }
# |3 B9 [$ U9 I0 n" N9 E! a i - ; f: }! D C' q9 r( E" j# h
-
, y$ f: n1 R: x - }
复制代码 //TIM_TIxExternalCLK1Source_TI1: 滤波后的Timer Input 1
% ?, N. x6 j A# Q6 J% v//TIM_TIxExternalCLK1Source_TI2: 滤波后Timer Input 2
- X6 y" L' u7 j5 F9 z1 b$ ]% }
0 A3 K3 \! y, u" { c5 g C x, ?6 z% t E1 Z0 ~
这两个选项T1是CH1通道 T2经测试CH1与CH2通用
& h6 G6 G7 X' x5 g9 k: E1 X* E. [ C0 ~' t* z8 ^; z0 O
% z* g( f6 F, \- q大概是这个异或的原因
4 n1 h3 O* F8 c' J: p
2 k2 |% w0 n# ]% t. a( F外部时钟源模式2
0 U9 `1 b1 y( s' d2 R4 R9 W7 E5 C" `0 w% {0 u3 Z! R/ h
来自于 外部触发脚[ETR脚] 经过极性选择、分频、滤波以后的信号,经过触发输入选择器,连接到从模式控制器。当然分频和滤波不是必需的,可以根据外来信号频率高低及信号干净度来决定。1 h5 I S2 g0 j$ J
& M! q/ Q! u) s1 A3 s2 J/ C% ^- ?) K6 g3 D
ETR功能较全可以完成T1的工作但仅限于CH1通道,可以经行分频( A# F. z. Y8 a* @2 d
; e* O4 z/ R c# ]+ ]* U
. R) c# o& v @0 e4 _. F相关函数! Q5 Q5 @1 R3 N, T- y( ^: q. Q7 B
TIM_ITRxExternalClockConfig(TIM2, TIM_TS_ITR3);* H6 `& Z3 d' A1 w3 b
//设置定时器工作于从模式,时钟源为其他定时器的输出分频.此时钟源无滤波+ D- T: b0 q7 p+ }9 O, ~5 {
//TIM_TS_ITR0 TIM内部触发0 TIM1
6 @8 j3 i3 v, M6 d7 U" m//TIM_TS_ITR1 TIM内部触发1 TIM2
: @* `6 W% ]0 V. p+ B6 O) ]! e//TIM_TS_ITR2 TIM内部触发2 TIM3- R- M( J, x C+ ?1 F9 P
//TIM_TS_ITR3 TIM内部触发3 TIM4
& h1 b' B* G* V; \
/ w( Q& C. V6 a2 q$ v9 k p3 I
/ l7 y l6 Q+ N+ V/ j0 G4 y TIM_TS_TI1F_ED
0 ~4 t: m7 K9 x/ r% h3 U0 ETIM_TS_TI1FP1% Z, H. z$ Q. E% i
TIM_TS_TI2FP2" f5 ?0 q7 i2 P- C3 U2 e
TIM_TS_ETRF
4 a# l0 @. F8 i9 h; U: W, y" R; Q3 e2 V. i+ f! n
/ g# g% U: L: W( p5 J' FTIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_DIV2,TIM_ExtTRGPolarity_NonInverted, 0x0);
+ Z2 V5 }) ~% S- @' q//外部时钟模式1.需要设置预分频,以及外部触发极性:滤波1 B2 R3 I( E+ d m
//TIM_ExtTRGPolarity_Inverted TIM外部触发极性翻转: 低电平或下降沿有效 //TIM_ExtTRGPolarity_NonInverted TIM外部触发极性非翻转:高电平或上升沿有效
3 A& L- ~/ m: P) r! D& @5 o7 g O$ j L. ^* ^
7 @8 D; M$ G9 E) M' D, a
代码示例
8 s2 {7 ?0 u% N3 k1 w( l; E% e( h由第一个示例更改,功能一致main不变
: F: m7 y1 I+ |" f2 R
, I8 m* o+ y0 A* i& T" g8 J- void TIM2_Int_Init( u16 arr,u16 psc ){
( S9 b C; B- M* E6 o - " W4 n' T* `7 [3 B | ~( N
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;3 j0 \7 c, w, ^4 X4 V) F
- NVIC_InitTypeDef NVIC_InitStructure;) B2 Y5 Q/ J1 R! K* d% X8 W& j
- GPIO_InitTypeDef GPIO_InitStructure;+ ^3 g) l7 o: }: R6 n2 F
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
: O2 R& r0 p6 l5 ]& G3 ] - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);, p* \" V/ W# o
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; . E4 ~1 B( }3 u" ?
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
# \* j( x- {! v* r7 ?5 h2 z p - GPIO_Init(GPIOA, &GPIO_InitStructure); ( o5 @+ ]0 X% X K# X$ m5 v, ^
-
* S8 o6 L) y% a1 w) d& y, R9 i - TIM_DeInit(TIM2);8 [2 F8 _1 Q# w7 l$ H
- TIM_TimeBaseStructure.TIM_Period = arr;
0 G) [+ ]4 C {4 D- u2 ?8 D( K - TIM_TimeBaseStructure.TIM_Prescaler =psc; # H4 ~! H5 ]# A8 t( O$ p
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
% m( D0 p. u3 O7 I# A( g - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
8 I) p% {3 g" h# V2 A, J - TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); % g6 {. B7 ~0 b8 w2 e/ x5 E: h3 d
* H5 P9 a) l P9 w" a) q4 d- TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE );
7 C0 f7 U* r. M; m& z0 h' r& I
5 o: P1 H) y3 e* M3 i5 r- /*重点*/
1 X# u6 `# U' c. f - TIM_ITRxExternalClockConfig(TIM2,TIM_TS_ITR3);//高级定时器开启
1 D$ J% e+ \6 L - TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0)//配置外部时钟2的模式;
- f) |) ]9 x" n# ]. K/ F7 R4 F - TIM_SetCounter( TIM2,0 );" |! ?; {1 p# \; \" A
- /
5 e5 f( k8 _5 n( K - 6 c' Y2 z2 Q2 X3 ^
- TIM_Cmd(TIM2, ENABLE);
6 o( H6 r3 Y$ u: H- P4 m
; z$ u! _# y( N( Y- e- z* g0 u" C) p- }
* b+ j. ]- i9 h$ Y, F3 f T - void TIM2_IRQHandler(void){ 3 }. R/ o* D7 y" X9 A
- / _$ q2 Z4 ^$ d1 c2 w
- if (TIM_GetITStatus(TIM2, TIM_IT_Update)!= RESET){
8 P* v, T- p# k4 Y7 a
; q: e6 r1 s T3 y$ S1 u- }
6 H& R- X1 y2 J: ]1 L - TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
, m1 R" |& G4 q" w - }
复制代码
u# |- \. r! ?% @
% P0 a8 `& ]" z8 W7 ?" z t |