你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32定时器原理与使用(内附代码)

[复制链接]
STMCU小助手 发布时间:2022-5-17 21:00
1.定义
* i! B! H4 [. O" r0 _' n& a3 C
- |" C3 D/ u: S, C  Y( O设置等待时间,到达等待时间之后执行指定的硬件操作。
2 ]1 ]4 z0 u1 p7 s5 N3 r- f! i% D9 Z: S6 }7 R
定时器最基本的功能就是定时,比如说定时发送串口数据,定时采集AD数据,也可以产生PWM方波等,定时器产生PWM控制电机状态是工业控制的普通。
! l  w; z+ f6 J* u1 L" l( I
8 S; u# m( K/ {/ R. ]$ k  n+ n  S2、STM32F4xx系列的芯片:2个高级控制定时器(TIM1和TIM8)、10个通用定时器(10TIM2-TIM5,TIM9-TIM14)、2个基本定时器(TIM6和TIM7)、2个看门狗定时器6 p+ r( D: }: s+ |( m" t$ F* ]/ d& V
5 F" V4 n, R1 z) N
具体可参考中文参考手册了解其特性及原理+ m4 X7 `) [; {2 U% ~* O
. e# W6 }' L; _2 b: Y% l  i- C
ALOXH[IK)RFCODGGI%%CWN2.png
3 @3 g- G% l- S1 y9 r
5 f0 v! w/ R) @; O# v3、定时器计数模式:
  {" k' x+ U4 R# m3 v9 {( K% ?( a% t; z- A+ ~% [
通用定时器可以向上计数、向下计数、向上向下双向计数模式。
; K8 E# u6 A2 e& P2 u( o$ Q/ T( |# u' U3 {' e$ t( G) M
①向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
; A; a9 A6 r5 M9 E
- k; z8 K" N7 q5 a②向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
" c& v4 N- ?  d0 G7 v6 e4 d( ~/ D7 x- Q+ f  a5 \* |
③中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。2 G1 o: b6 Y# c5 N* j' I

/ }5 x* q+ A4 m2 x+ O4 L" C如图:: ]3 D! ^% R3 M8 u
) d5 A) H' W3 _( v
M7EUO%%U%%LSE9G}TEN`(0Q.png
: r) W1 r, m# n" O3 C" r: }: r2 i3 F6 J: [' g; s
4、通用定时器工作原理:
  \- o. q1 q0 X4 @" @
/ p! X; i! z* N" J● 计数器寄存器 (TIMx_CNT)
6 I( m* _0 `( g, U. R3 P9 Y& X+ `( \- ]
● 预分频器寄存器 (TIMx_PSC)
% T3 v  z+ f. w. a: u) `( Y% S" Q. n: y0 N# v5 ^. J- @" e: S# U
● 自动重载寄存器 (TIMx_ARR)' a4 C" R" S- `9 e( |. l5 j7 A! I; C1 j
* u$ b; t& W7 M8 C9 p5 U1 }
假如是向上增长模式,计数器(CNT)从0加到自动重载值(ARR),预分频器(PSC)减一次。
$ \+ D7 I% R! U2 e" _9 g! q
! @; ?. ~1 W# s9 I, |3 _时间计算方式:
" `4 l) O* I( e3 X7 F" s/ q2 `( b8 z* L% A7 I9 p, H0 b
假设频率为:42M*2 == 84M == 84000000 == 1s //42根据定时器时钟数可知 并且一般都是*2/ x& ^5 V& p0 p1 f  V1 g
" c. I; q) ?3 |& {/ M
定时器定时1s产生中断:
3 F! P+ g# y9 ?, c4 y- w
, h. l! [# C5 r: L$ j3 o0 p# KARR = 84000; // 1ms0 F+ X# G0 \5 D5 C3 T: h1 ]9 m6 y) e
; Y( Q! t8 W3 i) F4 |/ H, o* R
PSC = 1000; // 1000*1ms == 1s
; Z* ~- t, Q& u$ O& r9 u1 S, _1 Q0 z) e0 m7 E2 X; X

/ D; i+ I8 }, x8 q& K& }) \# W
- p* T0 `( H' i% H2 y5 u如图:可知基本定时器的时钟是42M,那么对应*2就是84M=84000000=1S(ARR*PSC)& A* K! ~/ B( u5 G

5 z/ x/ }. A) r0 a. e# C7 l       高级的既是84*2=96M=96000000=1S
: A6 H- f" g4 \* ^+ |5 c7 \0 [7 P6 ]  l& W) H1 J! X3 s
UVE0S762IU1SYL8G5D{RZ04.png + g/ r/ c0 F1 z2 j" }: D8 z& T
. l! p+ ^8 s- ]1 I
5、定时器中断实现步骤
& @& s% u0 a1 _. P% c- W: u  t1 \  L- P: |: m
  1. //5.1、能定时器时钟。
    6 y1 |+ n0 j! K5 W4 I( x6 \1 f
  2.     RCC_APB1PeriphClockCmd();6 ^3 r) b/ S; {5 r
  3. 4 K' c- V4 C' |; u7 v4 C: e  j2 D8 h
  4. //5.2、初始化定时器,配置ARR,PSC。(申明结构体)" W/ m& e- u* r4 E5 Q; s$ L8 S
  5.     TIM_TimeBaseInit();
    3 q0 t. b) m. c+ l

  6. ( W! J; @$ a# T0 L7 M* T! o
  7.   typedef struct0 e$ o% `+ X; R
  8.   {
    % k) W7 v3 V( i* g4 y
  9.     uint16_t TIM_Prescaler;
    5 v. B* r- l* Y
  10.     uint16_t TIM_CounterMode;  g0 U% U8 k+ t* z4 _
  11.     uint16_t TIM_Period;
    ' G, W2 N) V" V' Y
  12.     uint16_t TIM_ClockDivision;1 y- j) ~! h8 A
  13.     uint8_t TIM_RepetitionCounter;
    % x& j  T3 n/ h% l
  14.   } TIM_TimeBaseInitTypeDef;
    ) |7 A8 V& h% u+ \3 U% q# A
  15. & P( X3 d1 w' V, h; l) z# c
  16. 7 Y4 U  k6 T  b7 S+ e4 m, ^
  17. 7 g% p! q6 @7 w* ]# c) d
  18. //5.3、启定时器中断,配置NVIC(申明结构体)8 x% m+ S, w# m4 C0 E/ R4 G
  19.     NVIC_Init();
    ( q  D. U( n0 }5 ^

  20. 8 ~8 y8 U2 I$ ]! x& ?8 ^* ^
  21.     进行NVIC中断配置  E- V9 @) j( Y) l% ]
  22. 0 D" L& ~9 h7 t, w2 A3 u; ~
  23.     NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器 3 中断& |) A2 c, l, O& }; G
  24.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级 1
    ! B9 h2 F( V6 V6 o6 F' ]
  25.     NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //响应优先级 3
    ' ?6 S. y' c7 b/ l
  26.     NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    0 ?0 p' f; Y6 p2 N% _" y+ E9 g% G6 Q
  27.     NVIC_Init(&NVIC_InitStructure);// ④初始化 NVIC: y0 I5 t8 H* d
  28.     TIM_Cmd(TIM3,ENABLE); //⑤使能定时器 38 Y- B. T. T+ x; X. P' D1 ^. _* }

  29. 0 e) v8 P$ G3 s' P/ n! e
  30. //5.4、设置 TIM3_DIER 允许更新中断, }4 j4 w% p. r7 @
  31.     TIM_ITConfig();& t* h1 o, N5 [* r. d% k
  32. : W' E; w/ D5 o" t
  33. //5.5、使能定时器。6 K; C) j" a6 ?; `% p- j; R3 G
  34.     TIM_Cmd();
    9 x) y+ G7 M  S* N5 ]" W5 o

  35. ) D3 `$ h  L6 v- U% N7 u7 ]& c
  36. //5.6、编写中断服务函数。, X+ {+ ?& {* a& i: H
  37.     TIMx_IRQHandler();
    / |$ Q+ A: V( I/ w' Y9 L* s
  38. 5 G4 q* g/ `$ N
  39. //定时器 3 中断服务函数4 }6 i' J6 o. b7 Z" _& k
  40. void TIM3_IRQHandler(void)1 ]2 F9 b4 n; ~5 [2 F
  41. {
    . c7 r  o, C% @- X$ c& \
  42.     if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断9 Z/ k$ t- J, A2 K' t0 S" V: I8 D
  43.     {# M" T7 T2 b9 f. e3 Q; H) y. ?3 i
  44.         /*处理的程序段*/
    ! H7 n# U, }& \3 M6 p. F
  45.     }
    - r7 }/ c3 b! d

  46. 1 r! O* [' J& a* |1 C8 B! j1 P
  47.     TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位( B4 m( O; b8 O" l" t
  48. }
复制代码
  1. TIM3_Int_Init(5000-1,8400-1);        //定时器时钟84M,分频系数8400,所以84M/8400=10Khz的计数频率,计数5000次为500ms
      t8 E! a8 G+ g
  2. $ L! L, P, }7 T
  3. void TIM3_Int_Init(u16 arr,u16 psc)
    . b; L" q5 }# g4 |
  4. {
    7 A/ {/ S1 |. D& b
  5.         TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;0 z2 j/ J" R* i; |& i
  6.         NVIC_InitTypeDef NVIC_InitStructure;, f1 {9 y( a" v  M" D0 P
  7.         1 ^2 g: r2 s/ b2 N& ^4 h
  8.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  ///使能TIM3时钟$ ]# Z& A$ [1 k" g
  9.         $ U4 G% I: M" h& T
  10.     TIM_TimeBaseInitStructure.TIM_Period = arr;         //自动重装载值
    # D" _' n! z9 [- v8 r  W/ T
  11.         TIM_TimeBaseInitStructure.TIM_Prescaler=psc;  //定时器分频
    . p/ T9 f7 J8 e' z+ t0 P
  12.         TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
    ) l& q8 m1 i4 r) {) ^4 {
  13.         TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; & l0 \5 s9 V# P% l7 r5 }
  14.         ' f' D& Q- Y' @6 P" d
  15.         TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3! T5 v) |. ^" i  ^
  16.         
    9 y' }. a0 c' h* `0 F. P0 B7 i
  17.         TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断2 T2 m- P8 I& Y+ k% f
  18.         TIM_Cmd(TIM3,ENABLE); //使能定时器33 X, R6 w) T( A4 i) Z
  19.         $ o- Q- q) r( a" t7 C
  20.         NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断4 y# K7 ~1 ]9 }+ \1 M4 a
  21.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1" m$ W0 L1 g% i( H- e" Z6 d* \0 |
  22.         NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
    * |. O& \6 J1 `# i, r
  23.         NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    + v+ L% a6 E1 _/ y  N
  24.         NVIC_Init(&NVIC_InitStructure);
    9 {: l6 W: O5 O6 B9 a8 J
  25.         " J) @; N+ I/ Z7 {* Z- N  d
  26. }& ?, }; D  e2 M+ O$ }$ o) z

  27. 4 k; u6 w! G! W# k
  28. //定时器3中断服务函数
    , {4 K6 ^/ f7 ]9 I$ L
  29. void TIM3_IRQHandler(void)
    6 m: Z3 n# ~4 H* ~9 e7 V
  30. {
    3 V2 Z; V+ B: U+ F- `
  31.         if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断7 r, ^$ C! C7 ?8 M4 T6 ~* |
  32.         {
    0 I; O3 }7 A7 |/ f% v( A8 d5 \
  33.                 LED1=!LED1;//DS1翻转  @* b1 b# e: E
  34.         }- i$ {# B8 I% ?0 r) O/ C
  35.         TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
    ( d9 d& l& f: X2 ~
  36. }
复制代码

  _7 N# P- o# P7 u
' l9 S  i2 b# y! B0 r$ `* I9 c5 ?4 ]. B1 U) f% O$ }

5 J3 }; x1 Q* ?4 J: e4 T
赞 收藏 评论0 发布时间:2022-5-17 21:00

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版