基础了解2 k$ M+ s* \- g4 v/ Z6 O
时钟选择计数器时钟可由下列时钟源提供:
9 n5 N4 Q& i9 q7 w$ q; R7 {: @, c
" }! s0 ?5 N' q, O
0 N% g6 m; t' u# H● 内部时钟(CK_INT)5 B& p/ J; z: H3 ?4 Q c
● 外部时钟模式1:外部输入脚(TIx)
; O$ j4 _1 R3 h- H) J. U● 外部时钟模式2:外部触发输入(ETR)
9 s5 L( R6 U# E● 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器6 L+ d5 O' O2 G& v* g( I: E ]+ _
. n2 t/ k3 m) n! [4 E: A8 a' Y8 b8 m% r8 b
在平常使用中我们系统复位 000 默认使用内部时钟源4 J# g/ F. {/ P) N! c1 }. h
" h) T& n) s# |8 y/ Q$ j7 k7 b1 O8 K9 J- o* E0 H' Z% y
内部时钟源* Q, m8 G! O5 e2 u1 o0 S' P
从时钟选择框图中可以看到,内部时钟源(CK_INT)来自RCC的TIMx_CLK,即定时器本身的驱动时钟。( v& ~% l; O! X% P1 L# ]
% e0 V" j4 q- u9 x# D' ]9 W+ e6 w: J7 u
当禁止从模式控制器(TIMx_SMCR寄存器的SMS=000),则预分频的时钟源CK_PSC由内部时钟源(CK_INT)驱动。定时器的实际控制位为CEN位、DIR位和UG位,并且只能被软件修改(UG位仍被自动清除)。只要CEN位被置1,预分频器的时钟CK_PSC就由内部时钟CK_INT提供。
" @- T# i! N2 Y, b l
+ g- C& P- \1 |# u
& ^2 d8 d% D2 U I8 f: D 通用定时器的内部时钟来源于APB1总线时钟,但是通用定时器的内部时钟是根据APB1总线时钟是否分频来决定的,如果APB1总线时钟预分频系数为1,则通用定时器的内部时钟就是APB1总线时钟;但是如果APB1总线时钟的分频系数为2,则通用定时器的内部时钟就是APB1总线时钟的2倍。$ e+ ?# b! T% N0 B' |: E( a0 c
: V- U* W( m9 G- S) V9 W9 i
" Q1 a6 x5 O4 n7 B' l
下图显示了控制电路和向上计数器在一般模式下,不带预分频器时(分频系数为0)的操作。
( e+ u: b& j' @+ G4 b% @" y' F2 ]% ~$ ?) g
如图所示,只有当CEN位被置位高电平的时候,预分频器的时钟CK_PSC和计数器的时钟CK_CNT才开始工作。5 s) l7 z- E0 l. P" N
" U T# M: x7 S; X5 k# k
" C1 y1 P: \8 }, g9 e, E, V9 P
外部时钟源1* Q+ ?) U8 E( _6 {
( ?* o; T5 \/ e& S6 ]$ A/ s来自定时器自身输入通道1或通道2的输入信号,经过极性选择和滤波以后生成的触发信号,连接到从模式控制器,进而控制计数器的工作;
' F! X" m' u- P. c2 @% y$ B# a# A7 B. u/ r1 d, N
# n# Y; ~5 {$ s7 t
来自通道1的输入信号经过上升沿、下降沿双沿检测而生成的脉冲信号进行逻辑相或以后的信号就是TI1F_ED信号,即TI1F_ED双沿脉冲信号。/ Y' j W& w* A0 _' l& b2 L5 t
; G) N2 T; f/ U3 p0 V( \5 x4 `7 ~
# P/ d9 W: H: x相关函数
9 I* A% ]% k! y4 YTIM_TIxExternalClockConfig(TIM2, TIM_TS_TI1FP1,TIM_ICPolarity_Rising, 0);
" f$ w- u- O" i! j2 z/ r: T//设置 TIMx 触发为外部时钟(从四个通道引脚引入)# M. Y7 R) |) `! h8 B
//触发源选择:
0 p% B. V4 L7 F2 k3 R//TIM_TIxExternalCLK1Source_TI1ED: 双边沿的Timer Input 1
* H8 { d' g. _9 r//TIM_TIxExternalCLK1Source_TI1: 滤波后的Timer Input 1
6 _* b1 a' l, [! [& ~//TIM_TIxExternalCLK1Source_TI2: 滤波后Timer Input 2, h9 E- A$ r! r9 C4 D9 l7 O
//设置输入捕获的边沿:# j+ k* i) Z/ t* W B
//TIM_ICPolarity_Rising8 g# \% A6 S3 G. m2 ~
//TIM_ICPolarity_Falling
, D+ i. g* G9 v- f3 p
" B' h( X0 x' B( ?* X* w) U& o( u2 |" ` W
//TIM_ICPolarity_BothEdge3 p. W2 f8 ?) S9 Z ?/ J7 p' e
8 ~- [0 D* D1 R s/ q2 a$ {* ?, v$ L }
//设置滤波设置:
5 Q) @' _. z# s) ?3 Q//必须在0x0与0xF之间
8 C, o3 ]5 C1 H; |; f* d: G. o$ l. n% u- ~. C6 Q! V
. @. `0 i% u. i. P3 o& n
代码示例
' y6 ]+ K; |4 [! _. k: K时钟源对频率进行计数
5 }3 i3 U6 R' E1 J- #include "timer.h"
: y2 y4 [3 W* K5 [! j/ r - #include "led.h"
. c5 j. f" T3 U+ [7 p8 q7 d. k - // 1 A8 _- F# L N% G! N# m3 }
- //将PB5与tim2-ch1的pa0短接
1 _4 T- _5 u, @% d3 J - pb5为时钟源对频率进行计数4 P: I$ J- X+ i/ }
- * h3 |4 t1 u2 c) w& q" ^
- void TIM2_Int_Init( u16 arr,u16 psc ){
$ W8 ]# _$ S! y4 m* O
- `+ z% Q5 |' O+ {% z5 o8 S- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
% y0 B7 V: i) c - NVIC_InitTypeDef NVIC_InitStructure;
" ] S: J8 O, `; ?% S - GPIO_InitTypeDef GPIO_InitStructure;$ O! W8 |- F2 E9 q% Q
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
% V, _+ G2 K4 J7 f8 }" B - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; : m6 ]5 T5 C5 l# k+ o4 k8 q- j
- GPIO_InitStructure.GPIO_Mode = % I. Y" K$ O- h8 Z' I4 E
- GPIO_Mode_IN_FLOATING; . t) j1 n& V9 W* y+ n
- GPIO_Init(GPIOA, &GPIO_InitStructure);
# h: r9 N- }' |2 x% H. N% P$ i/ V3 a - % A5 [( \$ k' `! H. F
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); ) u' \- R/ ?2 h
- TIM_DeInit(TIM2);
8 a, i. c V1 o3 S5 |* J - TIM_TimeBaseStructure.TIM_Period = arr;
$ r' f! a9 R' x* \. F - TIM_TimeBaseStructure.TIM_Prescaler =psc;
% y7 D8 `1 ], s8 X" x) l - TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
4 q, A: u2 L& h1 }" m - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
% p6 S* X. g- W- p5 [% Y' I - TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
" M+ W+ G3 \- t# m B" J - / \+ x* }( W( F7 e( G
- TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); ( N$ p! g3 a, I
- /*重点*/ & U6 V# p& h' f% T! w1 p
- TIM_TIxExternalClockConfig(TIM2,TIM_TIxExternalCLK1Source_TI1,TIM_ICPolarity_Falling,15);//设置输入滤波和边沿检测 `6 |) n* x9 H2 ~, z/ K* F" Z3 P4 `
- TIM_Cmd(TIM2, ENABLE);
4 f( o9 u- {% W/ E0 F - //
3 }+ f# B. z# ]0 {9 H) w+ n- L - }2 ?( R0 d+ P( f$ f9 F4 g
- 9 P1 v4 v+ ?& O7 T0 h# n
- void TIM3_Int_Init(u16 arr,u16 psc){
4 O$ {* o+ o" [7 C9 a2 c - ! l- w- [2 D/ w& s
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;* C$ u' [+ N$ J' a+ J3 Z
- ?0 i/ q6 x: N- c
- NVIC_InitTypeDef NVIC_InitStructure;' g2 [9 L4 Y4 c- e y+ J
7 V; `: }( n* a' M, e8 k7 x% e-
3 x8 W: I _3 R9 q" D5 G/ H
$ z8 i$ M9 t% q, ?. B& T
9 n2 ^/ \! E0 S% `) D7 @- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
! l9 Y+ S4 U. V; x8 @2 F - TIM_TimeBaseStructure.TIM_Period = arr;
4 J9 N, F5 v/ d0 b4 \3 W - TIM_TimeBaseStructure.TIM_Prescaler = psc;
$ J1 y3 _8 F0 w* L# ]4 b - TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; + E8 L; u; V9 y
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
' Y A/ B* p) b/ C4 M" Y0 p - TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); ) V& B1 B1 u2 A. Q0 G& {7 x/ A
- 2 {! X* ?0 U: l* x# r- Q
- 3 A/ a; _0 s# G3 j& f$ p4 r
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); % x: u* p3 K5 D' V/ l
- NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
7 S5 B7 R5 k" _0 _ - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 5 D/ n- i6 ~" |# j: ~: F- u8 | {
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
' c' _9 Z! y* A2 o' } - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 6 A7 n- G3 Y: Z9 U- J
- NVIC_Init(&NVIC_InitStructure);
9 J" O- m9 N: U5 E- z8 e. e
) ?! s, r& \: ]4 I b" x- TIM_Cmd(TIM3, ENABLE); $ F1 U: G) y2 f5 ` X1 X
- }
6 W0 [+ M3 A7 c7 Y
9 K# ?, @ [7 k3 [$ v" f1 R- void TIM3_IRQHandler(void){7 ]! w; P# C0 p1 d( ^3 y+ @4 f! T
. y% o) U' |( M: J7 b6 I7 o; t- if (TIM_GetITStatus(TIM3, TIM_IT_Update)!=RESET){
3 ~. K8 ~$ A- A9 t4 N* r; H# @/ I - LED0=!LED0;
4 ^% G# k9 f) _$ A: I - }
% E4 ^% [& ]: j+ h3 F; }! H - TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
) L- k' O: x7 G G1 C5 Z - }/ Z ? w- i: ~
- #include "led.h"" v+ _+ S ?) |8 g
- #include "delay.h"& ?3 \! C% ]+ }7 I1 f
- #include "key.h"# h6 g1 H% Z. }9 a& h6 |" Y, s
- #include "sys.h"' c% J0 U$ ?1 g, E8 ]7 \! g8 h, N
- #include "usart.h"3 n l! [- V3 j" ^( w
- #include "timer.h"
7 D* F! e# q4 d6 }- J: g) ~8 Y/ \
+ j# i! v! z% o; X( U- int main(void)
. V4 L7 H1 ~8 a+ z& G6 S4 {- ]+ A! o - {) r7 n3 }/ ?$ o/ W* H1 y
& U; i5 R" u3 b" {- delay_init(); //延时函数初始化
^7 m# `5 z' i. y% y1 B! | - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级( Q. r) x3 d t$ q. f/ h, j" }
- uart_init(115200); //串口初始化为1152002 w3 m) J7 F) `
- LED_Init(); //LED端口初始化/ [# H. M2 M. U/ Q/ [" S
- TIM3_Int_Init(4999,7199);//10Khz的计数频率,计数到5000为500ms d- H2 J% |/ I
- TIM2_Int_Init(10,0);
( M$ t( @# [2 k N0 B+ l2 K
, @! C- F0 d7 ]3 ^-
7 R) O& t* f) J: L - while(1). E$ T& g* B( c/ v3 U
- {6 _+ N9 D( v- o. D. Y& b
- //LED0=!LED0;1 n/ X2 m( G0 f! g; J
- delay_ms(400);7 o4 ~( Z' x6 h H
- printf("Count=%d\n",TIM_GetCounter(TIM2));5 W4 \2 J, l6 T. r- o" P
- }9 q b* y9 b$ S7 U; i
- ' G% C" n' ^5 d* z: U! e2 Z
-
; _# ~/ N* T+ |4 {4 V - }
复制代码 //TIM_TIxExternalCLK1Source_TI1: 滤波后的Timer Input 1. I# b3 d# i6 c4 n8 G4 c
//TIM_TIxExternalCLK1Source_TI2: 滤波后Timer Input 2
# ~9 D2 g' A" ~( ^0 q& r0 t% X/ l. z" F- j6 O7 Z. [
# I7 p7 c8 A3 ]( a5 U6 j这两个选项T1是CH1通道 T2经测试CH1与CH2通用
2 f* S! ?. L! |' \$ `; S0 p! B2 L& I) }7 |# ?! f8 W
6 M2 n9 m3 d) }- s a$ Y大概是这个异或的原因
# q. c* E9 E5 K+ {) v- Y# V/ e, G
外部时钟源模式22 ?+ E# e" _- ]/ N6 L
1 f$ @ ~4 y9 a- \
来自于 外部触发脚[ETR脚] 经过极性选择、分频、滤波以后的信号,经过触发输入选择器,连接到从模式控制器。当然分频和滤波不是必需的,可以根据外来信号频率高低及信号干净度来决定。: z! H) L# E0 |8 P' F" j0 [
9 ] z6 q5 y; B
# O$ t; |' t: f" {* {$ s" dETR功能较全可以完成T1的工作但仅限于CH1通道,可以经行分频
' A5 U6 ?# R' j6 V1 R! ]9 ]
( Q( z6 K/ B: R7 A' U
1 U5 M+ y- R0 e& t$ T( D! Q相关函数
6 X5 l2 ^' Z; J- k+ XTIM_ITRxExternalClockConfig(TIM2, TIM_TS_ITR3);6 ]% `, l. ^5 r* i* J |
//设置定时器工作于从模式,时钟源为其他定时器的输出分频.此时钟源无滤波
+ r. @. I7 j7 {& ]//TIM_TS_ITR0 TIM内部触发0 TIM1
& u8 E# z" r6 t# t( Y//TIM_TS_ITR1 TIM内部触发1 TIM2
* L. R! M# f. A# b* H7 b2 T2 M) l' Z/ g//TIM_TS_ITR2 TIM内部触发2 TIM37 h9 y R, Q+ ~% K
//TIM_TS_ITR3 TIM内部触发3 TIM4
/ o2 K* L8 m) b# x# U
' p. K4 o+ R g K" H. Y" j: c2 b4 i1 M1 L
TIM_TS_TI1F_ED. R- g; c' P0 h7 `. L
TIM_TS_TI1FP1' ^& D4 p! @+ E
TIM_TS_TI2FP2
+ o! b6 u. t; A+ Q TIM_TS_ETRF3 z0 G8 [! l1 l- _
0 k$ ?8 f- @% {% `* M& B" a
( ^( q+ p3 |9 UTIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_DIV2,TIM_ExtTRGPolarity_NonInverted, 0x0);
) J0 o9 u$ s+ J( V+ Y- T; H: r//外部时钟模式1.需要设置预分频,以及外部触发极性:滤波5 J0 ^0 V* ?! I
//TIM_ExtTRGPolarity_Inverted TIM外部触发极性翻转: 低电平或下降沿有效 //TIM_ExtTRGPolarity_NonInverted TIM外部触发极性非翻转:高电平或上升沿有效
: w4 O" _6 L( `" h. e
1 n( x8 t2 M% E
. d# [/ i- t: j. E M# H# O4 z4 [代码示例* K# z T/ p8 I/ w5 |8 p5 q
由第一个示例更改,功能一致main不变
" n4 X4 p; \9 ^5 @( v* b# y p0 A c3 q% x& u k
- void TIM2_Int_Init( u16 arr,u16 psc ){$ P+ t! o V( f% ^: M
$ @4 q* {3 s, I0 |% \/ b- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;- {0 u/ D e# S
- NVIC_InitTypeDef NVIC_InitStructure;$ ^6 C4 K: I) ?8 Z
- GPIO_InitTypeDef GPIO_InitStructure;" \# l E" |: C
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); ( Z* C+ r: h/ R( B3 I/ v
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);' A# x }8 n& r2 G, J, `7 x
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; ) z; o2 m* Z3 ]) Q5 e
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; # t. S2 q) y% X
- GPIO_Init(GPIOA, &GPIO_InitStructure); v& l* P; b5 X5 C/ X$ W
-
% i; s9 \8 [+ L' W9 \ X3 U - TIM_DeInit(TIM2);
9 i7 D& }' F7 |0 T+ T$ t - TIM_TimeBaseStructure.TIM_Period = arr; " M& | z6 X" b1 e
- TIM_TimeBaseStructure.TIM_Prescaler =psc; ' a/ f# D& _& }3 C6 |; S
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
$ M& A1 {9 d9 Z - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; # _. M& g2 I$ t& S; ]
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
1 V3 Q; @" \0 Z1 }, `+ x - 9 i# X7 ]( B e2 p2 i+ v7 [
- TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE );
( y0 d% R; W/ w - ! k0 T7 W) z" o$ \" G
- /*重点*/
4 E4 L- w) w) O+ e+ p6 L5 ?" ~ - TIM_ITRxExternalClockConfig(TIM2,TIM_TS_ITR3);//高级定时器开启' z7 X4 f& ]8 F$ W
- TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0)//配置外部时钟2的模式;
, n d" X" }& m7 d/ C- U - TIM_SetCounter( TIM2,0 );( i [9 x! H2 o; }, j# ]
- /
0 r y% M d3 `, T) L5 W( y - % r. f" q6 b* L' P! |
- TIM_Cmd(TIM2, ENABLE); ) ]: o1 q0 a" a9 k3 p1 @$ d: r; Q. ]
- 9 {; [5 L$ {% k& R1 H5 w& n
- }4 `5 h( f* a+ X
- void TIM2_IRQHandler(void){ " ]8 N; e4 |7 e( d7 N* E1 z0 o
) b. ~' k i/ L/ M- if (TIM_GetITStatus(TIM2, TIM_IT_Update)!= RESET){" |" x' l& l; j2 J; e# P7 U
- 4 G R) M/ }6 v
- }
6 ^/ z) Y& p7 {- a- J! i' O/ t/ _. I - TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
$ w$ ^6 P. @. q* P4 A5 l0 h - }
复制代码 7 F8 ~+ e, V( g
9 u2 Z' X" ^4 V" q6 u4 h: B, D
|