01、STM32捕获功能
6 V, q# O2 D8 d+ ^从STM32的定时器框图中看
: }, _( B9 E8 ]3 B
8 o- f! f- K7 L8 }, ]% r7 s* k4 F
- o/ K+ q* `9 I* g( M3 F
4 r( Y0 X; z8 Z: z( y. w. [0 c①部分基础定时器模块。# b# \) D. Q2 T3 Q) V2 c
" e8 d2 i- ]" K: @* M# x1 e②部分捕获/对比通道模块。1 ?9 C" n) M. A! U. A
# o- t& @' J5 c! U# r' }3 Q$ @③部分是本文的重点,输入捕获模块。
: P; j* W- L" _& `9 u* v0 n( k* }# t% _% |
从上图可以看出定时器1共有4个输入捕获通道。
: U# d) e4 }. Z3 U" Z# M Z
2 K' e+ t5 D# R9 Y( b8 P下文以定时器1的捕获通道2为例讲解。
, C& e* i0 o5 R p n1 n9 f7 z8 p" H" |3 `0 d# t- B! n, w" \1 K
首先确定下对应的GPIO,从STM32F207数据手册的Alternatefunction mapping看出,定时器1通道2对应的GPIO有PA9和PE11,下文将使用PE11。3 M( |% q; @0 N% P$ k& x4 P9 ~- Z
! i0 A* m: {/ S+ h- f
5 g0 j0 y8 Y# [) j
/ b5 ]. G( M2 ?4 {1 ^* }$ T02、输入捕获过程8 F8 Y* ?. j% B2 C, j u
输入阶段采样对应的对输入TIx,去产生滤波后的信号TIxF。然后极性选择边沿检测器产生一个信号(TIxFPx),这个信号可以被用于服务模式控制器的触发输入或在作为捕获命令。在捕获寄存器前被预分频。- d. L9 e1 G; e1 I
3 _' Q; x) U/ Q3 r$ F) ?
6 x, W5 ~6 K: u4 U/ {8 h8 J9 P
' B1 W2 l* N+ L3 z+ q# y输出阶段产生一个中间波形,被用于参考:OCxRef(高电平有效)。链地末尾末尾决定极0性。捕获/比较通道1 主电路。
6 `! B0 L3 ?& X; X: c" f( s: v @: q- q4 G
①处主要是设置输入捕获滤波器,输入阶段采样对应的对输入TIx,去产生滤波后的信号TIxF。一般应用场景不做滤波处理,设置TIMx_CCMR1的ICF[3:0]=0000,只要采集到上升沿,就触发捕获。1 H9 p- J. w- K1 C2 s( V& }
" H1 ]4 G' P/ A! G+ q
②处主要是设置输入捕获极性,设置TIMx_CCER的CC1P或CC1NP位,如果通道配置为输出,为0表示高电平有效,为1表示低电平有效;如果配置成输入模式,该位选择是IC1还是IC1的反相信号作为触发或捕获信号。为0,表示不反相,为1表示反相。
8 l" L. X3 Z, }; G* g: t/ K" `
5 `( g6 V/ T9 s③处设置输入捕获映射通道,设置TIMx_CCMR1的CC1S[1:0]位,这2位定义通道的方向(输入/输出),及输入脚的选择:7 G4 G- ?7 D! [' w8 D
0 b2 S$ u/ @. e& ^: A$ z0o:CC1通道被配置为输出;6 B0 G8 t0 {( u) }, k0 N, _, X
: I+ O$ y. b( t6 S* V( N$ b3 p01:CC1通道被配置为输入,IC1映射在Tl1上;
( E) O) @" J6 z" n8 [! Z* M# W4 m7 E/ Z0 O, X1 q+ k1 ^/ M
10: CC1通道被配置为输入,IC1映射在TI2上;
% l* r' T$ S3 P' c# Q4 j) S' a8 Z/ g3 h8 @
11:CC1通道被配置为输入,IC1映射在TRC上。此模式仅工作在内部触发器输入被选中时(由TIMx_SMCR寄存器的TS位选择)。
8 A; J/ v3 E O' w
, y& F0 u0 M E8 P. I) P3 s1 c# |④处设置输入捕获分频器,TIMx_CCMR1的ICPS[1:0]位和TIMx_CCER的CC1E位。7 v1 H: [8 {7 B7 p( F$ J- A8 _2 I1 L% z
2 P* @2 C" F1 o/ B/ Q! C
TIMx_CCMR1的ICPS[1:0]这2位定义了CC1输入(IC1)的预分频系数。一旦CC1E='O(TIMx_CCER寄存器中),则预分频器复位。2 H6 ^- o1 o4 \. Q2 i
! R/ {8 D. d W00:无预分频器,捕获输入口上检测到的每一个边沿都触发一次捕获;6 @$ i% ]: V& I+ j( l& P) K7 Q
5 M1 _, i, s; I& ^* x# W
01:每2个事件触发一次捕获;( Q4 c& V3 D% K: x$ |& w
- P' `) o8 X6 {4 u5 Y5 ?10:每4个事件触发一次捕获;3 S: m+ A3 G$ f( @1 g1 m
4 N' Y8 p1 A2 K4 C7 M/ I
11:每8个事件触发一次捕获。
; w" R+ u' H7 o9 f1 u$ s7 T2 Y# v
TIMx_CCER的CC1E位
) m0 {: y# ^- E7 e' J J* Z/ s) ~' {1 P
CC1通道配置为输出:
! k8 X7 ~/ h( F* `* v) D9 a: I
3 z; F* }7 E4 f. d. j6 F) X" E0:关闭一OC1禁止输出。
( H. r$ j& L$ v. C- s- s0 {
3 P: h) ^. y: q$ b3 q1:开启一OC1信号输出到对应的输出引脚。2 K) v$ [) m P
+ b/ t. ~6 o6 b
CC1通道配置为输入:- P# ?0 w: {( d3 V, C6 c
) N: E) S; ] c8 g) I该位决定了计数器的值是否能捕获入TIMx_CCR1寄存器。& v3 J% U( S8 D+ k0 y
G# v" @5 q1 @1 {1 D( t1 @
0:捕获禁止;
- F0 H& ]! y/ e i: G9 i& o2 h8 J! h2 g
0:捕获使能。
7 r5 h$ e M# _$ A
% W% t/ u5 C+ [- t; h8 u. f最后我们还需要设置中断,使系统快速响应输入捕获信号,主要是这只TIMx_DIER寄存器,如下:6 Q3 ?/ L6 j+ H0 G& N6 K* o4 C0 h
, n8 I+ X0 c: N& ^: i: I9 z8 W
; ? i+ y7 [ L4 _' g, D8 l; C; M3 L9 X$ ^- J# u) h, s' I
使能允许更新中断和通道2中断
y& n! h- p' B }8 b- s" m# m, A, J
' m1 O8 k; M- _
( m) D: ^3 G' \' C) h) O$ ~7 t
; u, n/ Y8 F" L1 v9 N03、代码配置
' @: ^ U# n* t+ {. {/ A1 k设置GPIO复用+ X8 ]) ~7 d& s
# C4 D; r! o) m+ i9 J- /* TIM1 channel 2 pin (PE.11) configuration*/8 o( Y/ a6 J6 }0 y# Z! ~$ c, P
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;8 {7 f8 n( H/ I+ H5 J6 r
- GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF;! W# s& \, O# l6 m4 N* i# Y/ A
- GPIO_InitStructure.GPIO_Speed =GPIO_Speed_100MHz;" e/ i$ H& E$ x3 _! X
- GPIO_InitStructure.GPIO_OType =GPIO_OType_PP;
6 U7 Z4 l! L' q- B4 x - GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL;
7 Z5 N6 E! i6 X - GPIO_Init(GPIOE, &GPIO_InitStructure);
[5 a9 x( B- a" z
6 M. [' W( P# r6 Q$ n G- /*Connect TIM pins to AF2 */
7 h7 `+ W$ \- U - GPIO_PinAFConfig(GPIOE,GPIO_PinSource11, GPIO_AF_TIM1);
复制代码 2 _; |% o8 Z- t% ]( b k4 f
设定定时基础功能( D8 h" {( Z7 r8 V, a
2 n% Z% N6 R C3 m% b
- /* Time base configuration */4 P u- y) B' M4 q- f
- TIM_TimeBaseStructure.TIM_Period =0XFFFF;, J/ Y: ]& ~5 m, I+ C6 K
- TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)((SystemCoreClock) / 1000000) -1;
9 o) v, l8 q& V l, f' K3 C1 B - TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1;
$ }7 S4 k) y) \. s0 F! x - TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up;0 E0 \/ ]# b: Z
- # J7 [. R4 ~ N
- TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
复制代码
9 }, N+ \: n$ k. E8 l配置通道2
" F0 d& L4 C2 w8 g# C
4 S" k& c5 Y( i0 W- TIM_ICInitStructure.TIM_Channel =TIM_Channel_2;
5 W' _5 S4 s8 J9 B0 v - TIM_ICInitStructure.TIM_ICPolarity =TIM_ICPolarity_Falling;# R% O5 q9 A- v4 u/ q
- TIM_ICInitStructure.TIM_ICSelection =TIM_ICSelection_DirectTI;
7 u& O. O) i( z* t% @% e+ a - TIM_ICInitStructure.TIM_ICPrescaler =TIM_ICPSC_DIV1;1 i# [5 o1 r$ m+ ]" }
- TIM_ICInitStructure.TIM_ICFilter =0x0;# G9 A* K6 _" I k
( Y4 n: e9 J$ i W# s/ J- TIM_ICInit(TIM1, &TIM_ICInitStructure);
复制代码
5 O- ^2 I/ `: U使能中断. B5 h3 m! [+ C
' `6 }" S. v# g8 E. t- /* Enable the TIM1 global Interrupt*/% Y! h5 z+ [- y4 L* |
- NVIC_InitStructure.NVIC_IRQChannel =TIM1_CC_IRQn;
. V# i" z2 Y z, Z9 _) p - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;; u8 b0 ]7 C |0 u1 K! G0 \; \6 o
- NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;% x/ m3 z: \: o4 O5 b+ s5 d
- NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;6 T3 p6 d( \3 L% S, O8 x. j0 P, K
- NVIC_Init(&NVIC_InitStructure);, L4 S, S# ]4 b& z( H- R) ~+ M, l
- 9 Y+ D" O; k, g
- NVIC_InitStructure.NVIC_IRQChannel =TIM1_UP_TIM10_IRQn;
) \( o- f- V. h, U: `0 p H8 `% D - NVIC_InitStructure.NVIC_IRQChannelSubPriority= 2;
" Q% [, J/ D; ^5 u+ a \7 f - NVIC_Init(&NVIC_InitStructure);3 i' H+ c7 k* G( ~4 {) D
- # i; ]. p: o$ {& k9 n! }! a! y8 x3 J
- /* Enablethe CC2 Interrupt Request */
: Z- v( _8 n5 V8 Q% ~6 X8 M1 Y9 P - TIM_ITConfig(TIM1,TIM_IT_CC2|TIM_IT_Update, ENABLE);
复制代码
6 t1 {* k/ ?3 a# m ~' v# {& Y使能定时器1
" c, x6 K$ Q0 x9 P& v) E6 Y
" c/ U. V: m6 ?% [" w7 P- /* TIM enable counter */
3 ]3 F) {# F( ?% u: i6 R - TIM_Cmd(TIM1, ENABLE);
复制代码
' B8 c+ e$ h2 \/ m4 o! d: [下载代码验证测试
7 H8 c! L/ F4 ` P' S1 [$ c2 d# H3 d2 B+ M f' D
. s3 t& t, A3 r( j$ S! m/ u* Y* H* v2 ~0 P& @2 p6 ~
% D& `# c8 }- ~) p8 Q E
/ Q, v/ } S5 q: H! D
. G6 u2 w# O! d |