基础了解
3 |! g7 ~! e" F" f+ @" l; U1 `时钟选择计数器时钟可由下列时钟源提供:9 V) N9 {- q- f& }2 e- O. C
0 D+ ]& d* H- m% j! N9 |
, J6 c: E% x! V$ S9 v% V2 Z● 内部时钟(CK_INT)" ~0 ?8 E2 }! \% Q9 N' q1 T1 x9 z/ W
● 外部时钟模式1:外部输入脚(TIx)
8 T" N% e M( n; D● 外部时钟模式2:外部触发输入(ETR)% l9 |* X7 @2 ^% P6 _( _
● 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器: G+ f, F. U3 d* ?9 b
4 X# ] F' _6 k( \! \" }, M: n6 d/ U# Z! a6 D: [/ @, A' t
在平常使用中我们系统复位 000 默认使用内部时钟源
; _1 [3 D6 Z8 o: Q# B2 s" C- `- T0 K/ E
- V8 y4 K( @' T8 K5 z7 [
内部时钟源0 w0 C6 T( { \, l6 ?8 o' M1 O7 ]
从时钟选择框图中可以看到,内部时钟源(CK_INT)来自RCC的TIMx_CLK,即定时器本身的驱动时钟。
5 K" \8 J% W: g# }8 {* E# b( @3 ^/ P
9 w. E* _# X, W; N) ~! `# Z5 p
$ w& z$ }6 B$ R3 c5 s 当禁止从模式控制器(TIMx_SMCR寄存器的SMS=000),则预分频的时钟源CK_PSC由内部时钟源(CK_INT)驱动。定时器的实际控制位为CEN位、DIR位和UG位,并且只能被软件修改(UG位仍被自动清除)。只要CEN位被置1,预分频器的时钟CK_PSC就由内部时钟CK_INT提供。 ' O2 b& y1 c+ S
$ C1 `! S- x$ L4 S
8 s) ~* ?' T$ ?6 ] 通用定时器的内部时钟来源于APB1总线时钟,但是通用定时器的内部时钟是根据APB1总线时钟是否分频来决定的,如果APB1总线时钟预分频系数为1,则通用定时器的内部时钟就是APB1总线时钟;但是如果APB1总线时钟的分频系数为2,则通用定时器的内部时钟就是APB1总线时钟的2倍。. c' B3 k; f( V4 ~, g- b5 {
, [9 a0 \7 X+ Q0 Y4 @" w7 e" B
3 q! G7 I. ]6 J7 h/ w* D7 C 下图显示了控制电路和向上计数器在一般模式下,不带预分频器时(分频系数为0)的操作。
) M2 F' ?, Y+ n; b+ W7 O
% _- Q0 y; l6 k3 [8 C7 R/ o! M 如图所示,只有当CEN位被置位高电平的时候,预分频器的时钟CK_PSC和计数器的时钟CK_CNT才开始工作。
5 X/ p+ Y% G) G) W& g0 r2 k! v4 M. R/ [3 \4 F% E
+ S& u* C* S5 t5 i
外部时钟源1
6 {+ M6 x$ v5 G# F+ S8 Z: d. G& y
" W3 @" D F4 v7 t9 q" x. }来自定时器自身输入通道1或通道2的输入信号,经过极性选择和滤波以后生成的触发信号,连接到从模式控制器,进而控制计数器的工作;# I- S0 c: H. |; }- C
1 O+ f& z& t1 F% a# L" b) W
% r4 N5 {2 `8 P" _9 Z* o来自通道1的输入信号经过上升沿、下降沿双沿检测而生成的脉冲信号进行逻辑相或以后的信号就是TI1F_ED信号,即TI1F_ED双沿脉冲信号。# o, R9 L8 b* K9 U/ c2 m7 K; g
2 ?, n$ i2 z% N
6 d: F: ^+ Q% o- {) c- H/ Y) x- x2 K相关函数6 ]+ H6 Y" g$ I
TIM_TIxExternalClockConfig(TIM2, TIM_TS_TI1FP1,TIM_ICPolarity_Rising, 0);* v, \- |, {* e3 h1 M/ K
//设置 TIMx 触发为外部时钟(从四个通道引脚引入)
2 ]0 W c) m, E! O//触发源选择:5 |8 A1 I$ B. q: S1 z
//TIM_TIxExternalCLK1Source_TI1ED: 双边沿的Timer Input 1
; h. r# Q/ g( o/ q//TIM_TIxExternalCLK1Source_TI1: 滤波后的Timer Input 11 R& [3 Y, K2 v( t4 L3 C, b. T
//TIM_TIxExternalCLK1Source_TI2: 滤波后Timer Input 2" n( h- J- r* D" @# @" O! l$ [9 l
//设置输入捕获的边沿:
# K/ E+ z% G: t0 x# x. J//TIM_ICPolarity_Rising0 y g7 r; O) n {* \ v. W7 R
//TIM_ICPolarity_Falling& r) `% r# G# g( P
( g0 f4 A( E+ D: u$ a
' s2 a8 F& p5 C' J1 f! N//TIM_ICPolarity_BothEdge5 e: R5 H# U8 w
4 v# w2 y# @# Z+ g* j
7 }) Q$ v3 p$ |; o//设置滤波设置:1 C" D- ]/ d0 N$ H: P
//必须在0x0与0xF之间
- B" |* s+ v* l% a
2 s- }& m7 w& Q; L ?2 ]7 ~" F& |/ w2 r. j3 d/ p
代码示例 |+ \4 n7 m+ E9 D
时钟源对频率进行计数
0 c6 H' O+ y+ m* q- #include "timer.h") a& Q2 T6 a' r" m7 A+ q) m m
- #include "led.h"2 C5 M L! B% V# K8 l# V( J5 v* J) H
- // " | `2 F% D6 z, r" Y! n. F$ \
- //将PB5与tim2-ch1的pa0短接. C q! h) K j( `1 h: Y9 |
- pb5为时钟源对频率进行计数6 ^0 S' w3 }7 v) D4 a$ F4 V
- # H; ?# L, S, e+ |6 S* w
- void TIM2_Int_Init( u16 arr,u16 psc ){
, ~; x* H4 b. T1 x' Y6 S6 f. w3 a
* E" ?9 z; f0 S& L) V4 b2 C8 m- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
0 n8 S h1 B$ a4 F+ e - NVIC_InitTypeDef NVIC_InitStructure;( Q: ^8 g/ P5 `# X; a
- GPIO_InitTypeDef GPIO_InitStructure;
$ u/ q9 c: O! k+ G( U - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
" x ?! l0 C; Q# E$ M: U/ P" ]/ q - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
# T. K, V1 z) m2 L9 a - GPIO_InitStructure.GPIO_Mode =
; w9 `6 Y* Y8 t: }! b6 q3 O - GPIO_Mode_IN_FLOATING;
" {; X) O: l2 C4 ?7 A. L6 g$ f# s - GPIO_Init(GPIOA, &GPIO_InitStructure);
/ G0 x. l3 O/ d! u# A: m
! \" B4 P; J, N. _! ?- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
6 p+ i# Y% K6 Z' D( H - TIM_DeInit(TIM2);
/ G9 g* W# l6 j; R7 n2 V7 E - TIM_TimeBaseStructure.TIM_Period = arr; * t' I l1 @8 m7 L5 e
- TIM_TimeBaseStructure.TIM_Prescaler =psc; - q, ?' e3 D+ K1 a0 S2 `
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
9 h) {$ ]. j7 T1 I. M. N - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; , U; O t& E( l0 n
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
3 I) E2 O' q/ [& v! K
5 @" m0 b$ z# I+ m1 t! T' O- TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE );
, f( |1 l8 M. U - /*重点*/
/ I8 h4 m7 E0 d& c8 m4 p3 d - TIM_TIxExternalClockConfig(TIM2,TIM_TIxExternalCLK1Source_TI1,TIM_ICPolarity_Falling,15);//设置输入滤波和边沿检测
7 Q8 A: c ]( u2 E$ ~/ B+ ^ - TIM_Cmd(TIM2, ENABLE); ! A* ?: w; s/ u$ \5 x
- //
_6 e6 _/ q! }9 e4 W6 Y3 t - }
% C& s' F5 d& Y. u5 y
0 o0 n0 R. s/ C. q- void TIM3_Int_Init(u16 arr,u16 psc){
- E: N1 @7 i) W8 m4 ]: j4 x, s) ^/ K! q' x
* a) m4 ~! [8 \. p k2 {1 k- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
( C1 N: l4 ~7 g$ @: G - ! q8 j$ R2 n- [( E
- NVIC_InitTypeDef NVIC_InitStructure;% s) u B0 `- [$ R4 z0 Z
- ( u" a/ o; l5 {4 z; y, k7 s9 m% w
- 4 S% T! J5 Y0 W2 A( f
- + t, g$ k& x8 h5 T
. j7 Z& O9 i6 L1 A2 D- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); : a, T( i# u* P# v" k/ @# {* F
- TIM_TimeBaseStructure.TIM_Period = arr; ; K4 C) S# v6 e0 K" @
- TIM_TimeBaseStructure.TIM_Prescaler = psc;
" @! j$ k& K9 U- @ - TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
; R7 u j6 d5 a) j- @. v9 T2 M - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; / g/ }0 v6 `" \: U* L6 t* z
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); A a! l- U$ j, C I3 x! _
- # d+ V) S% g' R/ P3 X, g, m
- 0 C/ v8 q" \) [
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); . [ }( p2 y. s; a k
- NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; 7 K3 X6 m ~2 m4 n) G4 y( w4 K
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
9 _6 Y+ k' \9 S, A - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; $ K O/ r8 g# A2 G. l, V
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 9 } e4 x2 B# [7 N) U& o ?
- NVIC_Init(&NVIC_InitStructure); 9 w, i7 X! h, X, \' F2 @
- 3 {/ {* x$ J! x$ b
- TIM_Cmd(TIM3, ENABLE); / U1 F( k9 r/ \$ @- g
- }
& n+ } K& d& B- M$ q2 L7 W
% ~) a1 w+ v, }$ w( L( h- void TIM3_IRQHandler(void){* y# D h3 r$ t
* s- F" y _; C# ^. f! P- if (TIM_GetITStatus(TIM3, TIM_IT_Update)!=RESET){6 y' M$ u7 N" c$ C( v2 }1 c
- LED0=!LED0;2 W) v) X/ J! M0 h
- }% E( o$ t2 J1 Y' W* R1 N2 o
- TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
: {) r5 q) B4 d - }2 `6 w9 z; D" N1 Z; o7 L7 d( |2 j0 Z
- #include "led.h"
/ ]5 F- x Q1 |7 s- i - #include "delay.h"- i6 T+ h3 L) u/ T1 D- f
- #include "key.h"
4 h, ^; D& g7 U/ _5 g, A - #include "sys.h") ]# l) s4 p7 t7 T4 H
- #include "usart.h"/ c$ O M. C2 t$ d7 ^! y
- #include "timer.h"5 n& V, L; I* N8 f3 {& m+ \
- }, f( A+ d0 J8 ^! b8 i- int main(void)
1 \/ E' |1 k& O5 O- X - {
4 Z: j9 Z6 C, x4 o2 v2 C5 ` k
6 t5 l: v4 y! G y- delay_init(); //延时函数初始化0 g- u* s% A8 S( B: ^
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级4 ]! y& i- D$ n* S0 ]8 ~! ?, Z
- uart_init(115200); //串口初始化为115200+ I' q3 x3 X W. u& _
- LED_Init(); //LED端口初始化
! z2 _8 `# G5 I1 z( G/ d - TIM3_Int_Init(4999,7199);//10Khz的计数频率,计数到5000为500ms* x2 z$ l/ [. @8 M* X/ b+ K
- TIM2_Int_Init(10,0);
1 J0 e3 U1 a9 E2 o! {& x - ! p0 X! }) r! R. E+ n3 C
-
! G; C' H: a" N. K' u - while(1)$ h" B9 i, c `: D2 s
- {5 C5 F& j( E1 }, S3 [% U+ p
- //LED0=!LED0;& t" s+ ~7 L5 ~1 _! q8 N
- delay_ms(400);& Y" G7 O& j3 u+ @7 u5 [
- printf("Count=%d\n",TIM_GetCounter(TIM2));: B& B. }' Y4 D5 g' {. u* V
- }3 `# j8 B2 u O% z1 @0 K* B3 e
- ( G6 I- P5 |3 _$ V) c" j
-
, F% p& e( F. ]$ }, b& F - }
复制代码 //TIM_TIxExternalCLK1Source_TI1: 滤波后的Timer Input 1& m; Y2 o3 d! i7 Y; X; }- P( F
//TIM_TIxExternalCLK1Source_TI2: 滤波后Timer Input 29 Y w9 {; x4 i4 V
- ~3 s X' S# e' ?: F" e! c
R6 l4 F& ?* ~' F. _8 ?这两个选项T1是CH1通道 T2经测试CH1与CH2通用7 L: [7 j* b' R# P( e& \! h
, u- W( o* @; P9 y) j; s: i+ R
5 e* j0 Y l, ]8 [& x大概是这个异或的原因+ j2 p* v+ e8 V2 K3 q8 i$ {* w
! I! ~. H7 @8 H外部时钟源模式28 M4 I9 r6 [! o6 H }/ h3 @
, \' a. W3 `6 v$ T
来自于 外部触发脚[ETR脚] 经过极性选择、分频、滤波以后的信号,经过触发输入选择器,连接到从模式控制器。当然分频和滤波不是必需的,可以根据外来信号频率高低及信号干净度来决定。: _, j8 A3 b9 q8 ?1 [+ O, x) d2 ?
: x! B" H' u" m5 i- I o1 x: v
" w' x8 B# Q& i3 k' NETR功能较全可以完成T1的工作但仅限于CH1通道,可以经行分频
& J" o6 y: h2 S, U, [' g1 V4 r6 \# r4 E! j! c$ p- ?5 g6 ?6 g2 U) j
0 }, I8 d1 |. r4 }' t相关函数
/ u6 x4 _6 k1 l& G6 R& |TIM_ITRxExternalClockConfig(TIM2, TIM_TS_ITR3);3 n$ Z- g. y; W% ^5 [/ s1 v
//设置定时器工作于从模式,时钟源为其他定时器的输出分频.此时钟源无滤波6 A* @2 T, W9 A! N/ Q
//TIM_TS_ITR0 TIM内部触发0 TIM1% W& Y& ^- i5 D g, ]4 B& s
//TIM_TS_ITR1 TIM内部触发1 TIM2
7 ` A" a5 B/ P: v/ x% k//TIM_TS_ITR2 TIM内部触发2 TIM3
: D7 P# _# b7 @# k; T; k2 S//TIM_TS_ITR3 TIM内部触发3 TIM4. w3 c7 @; W- f; n$ a, y! r1 R
2 ?" d$ i9 Z- K
6 d3 w& L6 ~$ u3 e TIM_TS_TI1F_ED
: E: b7 w7 l: \/ j4 U" i# O, UTIM_TS_TI1FP1
/ y E/ z2 u) q; `. Z& [ TIM_TS_TI2FP2+ H. q/ z2 d0 q
TIM_TS_ETRF
# I& d7 v1 W( {4 o& o5 d
8 e/ |4 S5 e( L2 X7 |# O. z
3 Z# y( y1 J% N2 pTIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_DIV2,TIM_ExtTRGPolarity_NonInverted, 0x0);
; Q* l9 |" F% w0 o1 v7 o4 g//外部时钟模式1.需要设置预分频,以及外部触发极性:滤波, n, N: z" m! K7 _
//TIM_ExtTRGPolarity_Inverted TIM外部触发极性翻转: 低电平或下降沿有效 //TIM_ExtTRGPolarity_NonInverted TIM外部触发极性非翻转:高电平或上升沿有效3 P, h5 v$ I6 q3 g; D* P1 s
+ ^. I& u$ I" c h% i! i, ]: v5 H
代码示例" D9 C0 F# G) E
由第一个示例更改,功能一致main不变4 `$ Q; e5 c& r' K1 S8 ?+ A
% _$ ^9 x- L7 i/ @; {- void TIM2_Int_Init( u16 arr,u16 psc ){
$ K, K5 l9 {1 O* Y% c$ w - 2 _) ]5 v. V; l1 t6 F' p7 w1 ~' x
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; f( F1 n2 e4 n0 S( E
- NVIC_InitTypeDef NVIC_InitStructure;* c1 e# h# x5 J: G, d+ {
- GPIO_InitTypeDef GPIO_InitStructure;" c7 R! V* C& z+ n; y
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
* c: ~& J7 I3 Q1 n! d$ g! O$ a% G; y - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);/ f) Z2 z* Y9 B1 Z
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 6 b* d1 K6 j& J6 a: N
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; " D/ V) ^ d; E! {% V7 I- l$ g
- GPIO_Init(GPIOA, &GPIO_InitStructure); / T6 O1 D4 x: {
- 9 l2 ]! f) G( }
- TIM_DeInit(TIM2);6 g! m. ^4 u, l6 N
- TIM_TimeBaseStructure.TIM_Period = arr;
4 Y, a: F& N8 O ?% I( a8 o - TIM_TimeBaseStructure.TIM_Prescaler =psc; * w6 h$ L+ W9 p. R7 j
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
* y+ z8 y) M% ]% _% z# q4 r( w - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 4 A4 z/ D0 t: G% M3 ]5 R/ _ s
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); & ^# q- Q) g \! ~& g- E) k
- 0 l4 Z' b. d* U* [. p
- TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); 8 k v3 u9 e. Y; ?- o
/ |9 ?3 b2 {1 G- /*重点*/- g" J# M( I* `7 p! S$ O
- TIM_ITRxExternalClockConfig(TIM2,TIM_TS_ITR3);//高级定时器开启, }+ q/ N& d" @ _2 I
- TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0)//配置外部时钟2的模式;
! i' V. ~: @9 i N2 q - TIM_SetCounter( TIM2,0 );
+ r! _. b6 S) g: X( ~3 [ - /" p5 ~$ L: n% |8 q, H) c+ A {
- . N6 |$ ]9 ?% c# u M5 I- `) g
- TIM_Cmd(TIM2, ENABLE);
' R! \. A+ ?! ~9 G2 k1 J m& b8 E" j - 1 i1 [& D: m Z5 S- H7 n
- }' |% F2 r* O5 {( W! f9 {- i) `
- void TIM2_IRQHandler(void){ . b* D& L" z- |) F! k! Q/ p- N
' H/ m9 T7 n+ f) F- if (TIM_GetITStatus(TIM2, TIM_IT_Update)!= RESET){
v! E8 _& q/ [4 E
# y: f2 z3 c9 o- }2 w- L- E' F& [5 i: U
- TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
6 [, N4 e0 g# o9 j6 k' W- Q" r, W - }
复制代码
: U& [ t( q. Z2 @& r: n5 p1 h+ V8 M G3 J7 w8 }" W4 c3 ?
|