|
STM32学习笔记07—基础定时器实验 % I1 `' s5 f5 S$ G( ?& q0 m
( V$ r) Z$ ~) ~
7.1 STM32定时器概述
9 R- j$ d: b, F STM32内部共有8个定时器,其中Timer1和Timer8属于高级定时器,Timer2~Timer5属于通用定时器,8个定时器的资源独立,互不影响。
6 p+ R$ y3 `3 y: Y! k STM32的通用定时器是一个通过可编程预分频器(PSC)驱动的16位自动装载计数器(CNT)构成。STM32的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)等。使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。STM32的每个通用定时器都是完全独立的,没有互相共享的任何资源。& k- ]9 g; @+ `& @- ~& r/ G9 I. `
通用定时器的内部结构如下图所示。
, `5 D8 x& v) i j: z& B- }- Y
# ?0 V$ P- s7 }- g/ c& M
7.2 相关寄存器
- c+ S# B8 K" F. k3 i- Y6 Y要使用通用定时器的基本功能,一共需要配置4个寄存器,剩余的寄存器都是在输入捕获和输出比较中使用到的。
% g- \& I) W# G6 z* H2 x) P7.2.1 控制寄存器1:TIMx_CR1& p8 P/ q9 T+ _" W
- V0 B; _, p8 }! I. S Bit 9~Bit 8:时钟分频系数,定义定时器输入时钟频率与数字滤波器采样频率之间的分频系数
{ S8 u' B$ J2 R7 }, `, K4 q 00:采样频率与定时器输入频率相等
* X" P6 q$ z- j Y 01:采样频率是定时器输入频率的2倍1 Q; `7 Z( ?' \7 B/ }6 Z" ]
10:采样频率是定时器输入频率的4倍
' C2 I: @/ O1 a/ D5 a0 Q: z+ R 11:保留
' g+ @ J) Z0 u6 z6 G( SBit 7:自动重装载使能
- z9 ?' c& r! w, F- O* t5 J: `+ T/ v 0:TIMx_ARR寄存器中没有缓冲0 T; k. s7 F# L
1:TIMx_ARR寄存器的数据装入缓存器
% J/ g% H9 c1 O; G8 ]' a" s: sBit 6~Bit 5:选择中央对齐模式$ O; ~0 v9 E, K) f8 c' O
00:边沿对齐模式,计数器根据方向位DIR计数% e# L2 s! p1 x$ d5 [! l1 U% H
01:中央对齐模式1,计数器交替向上向下计数,当TIMx_CCMRx中的CCxS=00时,计数器向下计数时被设置' X0 `5 E( a& X* ?2 t$ k7 G
10:中央对齐模式2,计数器交替向上向下计数,当TIMx_CCMRx中的CCxS=00时,计数器向上计数时被设置
) T( Z& t+ A- r& t: x 11:中央对齐模式3,计数器交替向上向下计数,当TIMx_CCMRx中的CCxS=00时,计数器向下和向上计数时 被均设置% E( q4 Y3 u- K/ ?- k
Bit 4:计数方向 d3 I6 O$ v R8 u# `6 I
0:向上计数,计数器从0计数到TIMx_ARR寄存器的数据时重新从0开始并产生一个计数器溢出事件/ ]/ |1 L$ A) ]2 E! M
1:向下计数,计数器从TIMx_ARR寄存器的数据计数到0时重新从TIMx_ARR寄存器的数据开始并产生一个计数器溢出事件
* [! W. C# z$ D5 xBit 3:单脉冲模式- k% P# g3 B$ o
0:发生更新事件时计数器不停止$ e: l0 P( a. Y [/ X2 ]9 h
1:在发生下一次更新事件时,计数器停止1 Y$ o( q, X) h7 E# a q, l
Bit 2:更新请求源0 g9 y4 G0 r( w
0:如果使能了更新中断或DMA请求,计数器溢出/设置UG位/从模式控制器产生更新都产生更新中断或DMA请求6 O$ C. h7 J0 n' B
1:如果使能了更新中断或DMA请求,只有计数器溢出才产生更新中断或DMA请求
/ S) {: [- K ~! k4 d/ DBit 1:禁止更新
$ G e% J; o, t9 h n) R" |- \5 T 0:允许UEV。更新事件由计数器溢出/设置UG位/从模式控制器产生更新事件产生1 K3 W/ h& G5 q$ v9 X: b
1:不产生更新事件
- P$ X8 d4 r" Z/ m& e5 C' dBit 0:使能计数器
/ c9 I2 x6 x7 G: Q5 X 0:禁止计数器: Y3 K' \- V" T1 R; D* W/ `$ g( j1 I
1:使能计数器& T2 F, e5 i( X+ ]& a
7.2.2 DMA/中断使能寄存器:TIMx_DIER
x. [3 }& Q& d$ O. Q- h
5 d& d# C& p5 N5 {" V Bit 14:允许触发DMA请求6 Y2 ]/ A( i: G% ~: t6 G
0:禁止触发DMA请求5 N% X. D+ `9 X8 L: H
1:允许触发DMA请求
7 U/ T3 y7 o* j+ jBit 12:允许捕获/比较4的DMA请求. m8 E, @) H4 _4 t* P* q- G
0:禁止捕获/比较4的DMA请求. @ O! g5 r$ Q1 f
1:允许捕获/比较4的DMA请求8 k0 O0 r# c! I4 J
Bit 11:允许捕获/比较3的DMA请求
: A8 C5 @4 v) w) v, I 0:禁止捕获/比较3的DMA请求- W: m; \7 K* i. u) \
1:允许捕获/比较3的DMA请求9 @/ b. I6 B* M# S
Bit 10:允许捕获/比较2的DMA请求+ W1 B- h& m1 X2 F! L
0:禁止捕获/比较2的DMA请求3 J( k9 x+ k7 D) `
1:允许捕获/比较2的DMA请求
, A+ e/ T1 p' |0 ^+ _( L, yBit 9:允许捕获/比较1的DMA请求
! Q" s8 g7 I3 q$ i3 H& `8 H, j" W) ` 0:禁止捕获/比较1的DMA请求/ c) V$ m6 y+ {6 r4 v: A, f
1:允许捕获/比较1的DMA请求 Z4 K% e/ m/ `# ?' c
Bit 8:允许更新的DMA请求
8 F- v5 c. m- C+ g 0:禁止更新的DMA请求& v2 K8 X9 u. }- a
1:允许更新的DMA请求5 Q6 H8 y3 B- s7 }0 V
Bit 6:触发中断使能
; t8 s. F+ e! `$ l" b 0:禁止触发中断
2 k/ H _: j# d2 E' E 1:允许触发中断: M3 @4 [4 o5 C6 Q
Bit 4:允许捕获/比较4的中断
2 N8 o4 j. u7 ?7 X 0:禁止捕获/比较4的中断
# `4 ^9 S/ C4 g 1:允许捕获/比较4的中断' d) P+ q) Q8 T
Bit 3:允许捕获/比较3的中断
+ a* b& p' M! ~: p! ] D 0:禁止捕获/比较3的中断
+ o% `+ M0 i5 Z% ` 1:允许捕获/比较3的中断. m* G, `& J4 `+ @1 P& }
Bit 2:允许捕获/比较2的中断
7 _; |& Y% @* Y' }/ w) M% ` 0:禁止捕获/比较2的中断6 j) N0 t8 x5 h: X
1:允许捕获/比较2的中断
6 R0 v& Q6 m; f# l- b3 eBit 1:允许捕获/比较1的中断4 R" K, H/ H- n. C3 i
0:禁止捕获/比较1的中断
/ ~6 K# V4 d$ w$ d% {. B 1:允许捕获/比较1的中断/ a$ N: p; w L1 D) Y
Bit 0:允许更新中断
: b# x0 M: g. A0 ~8 J( F 0:禁止更新中断
6 p8 D. T1 O0 s8 R' v 1:允许更新中断
8 @- M) ?3 Q7 U5 Y3 a6 e+ Y0 e7.2.3 预分频寄存器:TIMx_PSC) Z+ ~5 d) f2 D, T, O% p
Bit 15~Bit 0:预分频器的值,计数器的时钟频率计算公式为
, N+ A( }' X0 l
% T) l. n: r" T/ ^2 p: F+ V( e
8 ]% q" @/ P+ o: Z7.2.4 自动重装载寄存器:TIMx_ARR
3 E6 c! h! c0 U' f$ g: e( j
% E9 F) Y4 s0 v; H) x- z Bit 15~Bit 0:自动重装载的值,该值就是传送到实际的自动重装载寄存器的数值,当该寄存器的值为空时,计数器不工作。1 I7 M5 V4 B1 _) o% g2 R# G2 l
7.2.5 状态寄存器:TIMx_SR$ E0 J+ u+ c4 j2 v/ {) g; F
* n0 d, r1 f- O/ @& }: I- Y Bit 12:捕获/比较4重复捕获标记 _7 K& r: D- e$ w0 F7 W2 Z5 f
0:无重复捕获产生
0 p& t4 f$ [+ L4 E5 q 1:当计数器的值捕获到TIMx_CCR4寄存器时,CC4IF的状态已经为1' V7 k) J. z h3 T% M
Bit 11:捕获/比较3重复捕获标记8 ^" h* c4 F" y
0:无重复捕获产生
- ?- V4 a- z6 ]9 T 1:当计数器的值捕获到TIMx_CCR3寄存器时,CC3IF的状态已经为1
( l/ O5 [: F: b/ C/ R3 N3 vBit 10:捕获/比较2重复捕获标记
6 W! e; N+ e# i* v 0:无重复捕获产生
# h) o* x5 F5 v6 T4 l( o' K. T 1:当计数器的值捕获到TIMx_CCR2寄存器时,CC2IF的状态已经为1& n9 J3 S" g1 @* j
Bit 9:捕获/比较1重复捕获标记
$ A3 P* c: Y5 l/ N8 R6 V, b: m- f 0:无重复捕获产生' R6 d% Z* S& L
1:当计数器的值捕获到TIMx_CCR1寄存器时,CC1IF的状态已经为1
6 d: Q3 @) }/ TBit 6:触发器中断标记: B8 c4 L3 Q, O5 j# }1 E; M
0:无触发事件产生
1 L4 t+ U1 ^: [ T8 R 1:触发器中断等待响应4 C0 m+ h' [7 S. w- {3 K( d& p* f
Bit 4:捕获/比较4中断标记5 K. u+ c/ X" S3 ~, @/ k- R, {
通道CC4配置为输出模式:
1 i: `9 k! u$ _9 J) `5 p! p' H4 i, W 0:无匹配发生) g$ K& y4 E- P1 [ T* h- [
1:TIMx_CNT的值与TIMx_CCR4的值匹配6 V" _1 v8 Y( K
通道CC4配置为输入模式:
; P5 ~; N5 L( X) z( A+ v) z 0:没有输入捕获产生% w' y j1 d4 c' ^6 |
1:计数器值已经被捕获到TIMx_CCR4中(在IC4上检测到与所选极性相同的边沿)1 o0 p0 C1 D& P/ k" @
Bit 3:捕获/比较3中断标记2 k) _4 S% }) h
通道CC3配置为输出模式:
' w- n$ V5 P1 }( w B 0:无匹配发生
& h! S6 U$ y! _: i3 y7 F 1:TIMx_CNT的值与TIMx_CCR3的值匹配
: U' [* z3 C0 L0 E/ X% u- d$ B 通道CC3配置为输入模式:
. m" a% u2 K8 s8 E9 ?# y& D 0:没有输入捕获产生
, A) J% T$ J+ |. ^9 ^' G 1:计数器值已经被捕获到TIMx_CCR3中(在IC3上检测到与所选极性相同的边沿)
V$ t3 X1 S! M# WBit 2:捕获/比较2中断标记
. q3 M, u; }* B$ o' p' Q 通道CC2配置为输出模式:2 B* f4 _7 [1 T4 \) c" Y/ ^7 _
0:无匹配发生
' ^+ M6 G6 l! u* w8 _* U 1:TIMx_CNT的值与TIMx_CCR2的值匹配
, ?0 e! O6 a+ V) w0 S 通道CC2配置为输入模式:
: Q) X2 ^& I; c# S 0:没有输入捕获产生4 A$ L+ U/ B3 ]# v
1:计数器值已经被捕获到TIMx_CCR2中(在IC2上检测到与所选极性相同的边沿)
* u: ^+ H2 Q* j+ gBit 1:捕获/比较1中断标记
4 q7 ^7 ?0 ]- N/ q* f: r 通道CC1配置为输出模式:
! _. |' p3 o: W% d ] 0:无匹配发生& H3 C( o, {$ a& o. G" d
1:TIMx_CNT的值与TIMx_CCR1的值匹配% t/ ?# e4 h3 Z" y/ I" O
通道CC1配置为输入模式:
4 @- M% ^& @/ l! O$ o4 T) V& l7 E 0:没有输入捕获产生
3 u3 @, V; T. u8 X# s7 }) e% F 1:计数器值已经被捕获到TIMx_CCR1中(在IC1上检测到与所选极性相同的边沿)
K$ P! f' I1 L: w3 ?4 IBit 0:更新中断标记
2 K- c% Y5 o+ I" j* A 0:无更新事件产生; T/ p% e( S$ f" w
1:更新中断等待响应,当产生更新事件时该位由硬件置1,由软件清0
/ j' j! v, M4 ^) F# M7.2.6 计数器:TIMx_CNT4 S! E$ t# P7 m4 M- Q" L% V
9 e1 ~0 }6 _* q" Z* s" @2 `
Bit 15~Bit 0:计数器的值
! q) U* R9 X, q5 C; M7.3 定时器例程- P7 f/ e; l7 ?9 @0 X- z
利用定时器1实现LED以1Hz闪烁,LED接在PA1上。
/ {" T. [1 I3 _8 m3 y(1)创建TIM1驱动文件,tim.c和tim.h,并将文件添加进工程。) Z9 [7 ]9 l$ M$ W
5 B; }( R- O/ w3 V7 j: b5 u (2)在寄存器文件中添加定义如下图所示。
/ H7 y: t$ k% g* l- b. k; n/ @9 {2 X添加定时器地址
* n) }: m! w) c0 x" x# d/ \
. Y) ?# R- M& L& ^1 V7 r# R8 E
添加定时器结构体映射% e0 ]# w! S2 S3 B( M
6 [$ n6 [1 T4 i- o. s, }) {2 g8 _0 s (3)tim.h写入如下图所示代码* D( R& p+ S3 s3 J
' }6 m! r- p8 N' m4 \2 c
(4)tim.c写入如下所示代码
' ~ h1 l/ h1 ]0 S' t* h, L
4 J: l9 f: S. I- X- #include "tim.h"
. s! O" H7 x1 \& l9 A) d - /***************************************************
D0 z, e' f0 G0 q - Name :TIM7_IRQHandler1 u1 J$ |- `! i; K6 B6 c
- Function :TIM7中断服务函数
; C5 ]7 ~5 N; u- p8 B& f - Paramater :None
5 \. I8 g* {" U - Return :None: t( q+ m! Z+ V5 ^
- ***************************************************/$ ?/ h" C. r' d/ B$ Q
- u8 TIM1_Count ;
7 r G! `6 l$ [- V8 e1 A& Q9 p - void TIM1_UP_IRQHandler()7 T4 g: V7 y1 P
- {
; A" V* X# [( ~( P - if( ( TIM1->SR&0x01 )==0x01 )
- p) E0 |: l/ [6 ^. j: y1 ]3 O! E* w - {8 _ I/ {8 M. t, j x% }
- TIM1_Count ++ ;
0 ~$ X) t' O9 s C - if( TIM1_Count==1 )
# \8 |8 C+ n# d$ N; f# G' ~ - LED = 0 ; u! O. D2 U3 |! H' d |' p
- else if( TIM1_Count==2 )% L; f- @% l- E6 M# ]/ J
- {
1 o( B2 D- {: x U1 r - LED = 1 ;
& z* s) t9 I- @% Q8 a3 } - TIM1_Count = 0 ;4 R+ i% ~7 _9 g! y( `# p1 n5 `7 g6 g
- }
+ i( ^, k. U$ F- e - }
% X! }) C" G/ ~ - TIM1->SR &= ~( 1<<0 ) ;
/ S7 i" B2 V- Q" _ - }
( d, h' U7 ]. G# V( ]8 n+ q( S - /***************************************************
! d' ?. O" o; v - Name :TIM7_Init
0 N" {* p( Z/ r, h5 x$ S - Function :TIM7初始化3 \$ z! g% [* ]$ \$ W6 g5 ~
- Paramater :" W6 m- R5 g6 Q# e; E4 J: a1 r
- psc:预分频系数
# `) x1 ^: j3 u, p# ` - arr:重装载值
- w9 q( m- i- _ - Return :None
5 }" L9 _2 B; x) B; @- f0 F - ***************************************************/& i q1 l4 z+ W0 K6 m' t
- void TIM1_Init( u16 psc, u16 arr )( i1 Z4 I! T6 s7 ?8 K; }
- {
1 u3 H/ b7 k# [: s! [$ { - //LED初始化
1 p2 Z5 h" [& Z5 Y! U! D: d, p - RCC->APB2ENR |= 1<<2 ;
( \2 W6 N" j! u; K/ w - GPIOA->CRL &= 0xFFFFFF0F ;9 D/ Z$ n3 W0 U5 A
- GPIOA->CRL |= 0x00000030 ;
3 k, S [% F t6 c8 x* S4 O - LED = 1 ;! I: T; [3 y v* M. b$ W
- //定时器初始化
/ ~. o5 I# P; ]! S3 a& @ - RCC->APB2ENR |= 1<<11 ;/ j8 A! E+ I5 G% `) v
- TIM1->DIER |= 1<<0 ;2 `8 O3 l: I# S: o* o
- TIM1->PSC = psc ;
, Z/ Q3 s" r& T8 Y8 E0 V! Z1 H - TIM1->ARR = arr ;
5 y9 X# l5 q* r# s - TIM1->CR1 |= 1<<0 ;1 {7 P9 U/ t2 w _
- NVIC_Init( 3, 2, TIM1_UP_IRQn, 2 ) ;& u1 g' T0 T7 Z, C5 R
- }
复制代码
7 z* y. i8 d( T- b/ S1 Z1 D+ U8 _& f8 ?
(5)主函数编写如下所示代码( n# Z" \( [( s( k& F* z+ `1 j
0 _( t4 K5 J/ d+ K/ o
7.4 软件仿真截图* A3 S# h7 h) `5 w. ~+ h% I
1 F" }; S- n' W2 P" H2 K
+ L" O* U7 Y; Z1 F8 v+ P/ y' K) a
& ?6 [3 Q# H% Q2 D
% _- S/ a/ g# t6 B7 ~ |