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

【经验分享】STM32之通用定时器

[复制链接]
STMCU小助手 发布时间:2022-1-18 22:49
通用定时器可以用来:
1、测量输入信号的脉冲长度,也就是输入捕获(请对此四字短语养成良好的形象哈)
2、产生输出波形,也就是输出比较或者PWM(同上)
" t. \. E! G( a+ L$ k
     那葵花兄,通用的原理呢?又见葵花兄坦然自若的说:通用定时器是一个通过可编程预分频器(PSC)(注:这三个字母要有印象哈)驱动的16位自动装载计数器(CNT)(注:同上)构成。
    好了,大家撇开葵花兄,把焦点重新聚焦在我身上、那通用定时器有什么功能呢?我想肯定有人马上反应:有定时的功能、、额、、我也不能说你错是吧、、那我来具体点吧,其实也不是我具体,多亏了“葵花宝典”第STM32篇中文参考手册  :
1) 16 位向上 、向下 、向上/向下自动装载计数器 (TIMx_CNT)。
" b( |; R" _4 ~* v: d* m5 |9 f2) 16 位可编程( 可以实时修改 )预分频器(TIMx_PSC)(TIMx_PSC)(TIMx_PSC),计数器时钟频率的分系为 1~ 65535 之间的任意数值。6 C- w$ x5 o* ?
3)4个独立通道( TIMx_CH1~4 TIMx_CH1~4 TIMx_CH1~4 TIMx_CH1~4)
5 |/ j7 l/ Q# e% m1 z5 `A.输入捕获 ( K  Z' V. d7 ~. i. M0 j0 ?3 J
B.输出比较 & O; x+ g" @9 {- G% j6 L" E
C.PWM 生成 (边缘或中间对齐模式 )& ]5 N- e/ b, \4 @! N5 w7 y$ U5 }
D.单脉冲模式输出* T' U+ K9 o, Z. v, |4 c, `
4)可使用外部信号( TIMx_ETR )控制定时器和互连(可以用1个定时器控制另外一个定时器)的同步电路。4 i8 y1 L' q0 `, O3 }2 y( Z
5)如下事件发生时产生中断/DMA:
4 ^3 L5 u* r9 f, B5 f/ x/ eA.更新:计数器向上溢出/向下溢出,计数器初始化 ( 通过软件或者内部 /外部触发 )
( Q* i) k' ~, a7 ?4 h7 z6 O6 i( FB.触发事件  (计数器启动、停止初始化或者由内部/外部触发计数  )1 n8 z3 h& j4 C: _* w% o# p* k% u
C.输入捕获
! I  \& G6 u9 y) M; W, L6 Y& |. ID.输出比较
/ n- o$ ~9 v( kE.支持针对定位的增量  (正交 )编码器和霍尔传感电路 ) z1 R6 G% e4 ^, h+ l3 x- p! \
F.触发输入作为外部时钟或者按周期的电流管理
   当然啦,在此博客中不考虑那么多功能先哈、、先淡定、、若是被吓到了、、先去喝杯茶压压惊哈、、那我们怎么来实现定时的功能呢?
只要定时、当达到一定容量时,就会发生溢出、、聪明的人又知道我要说什么了吧?世上太多聪明的人了、、没错了、、把中断这位兄弟叫上、让溢出兄和中断兄合身、、(省略合身等待的时间)、对了、诞生了溢出中断、我们给取个好听的名字:更新中断、在这里,我们是利用中断来定时的、、
   接下来,容小弟介绍下与此博客有关系的寄存器(具体的位是什么功能我就不讲了哈,因为我们是采用库而不是操作寄存器,想知道的可以参考中文参考手册哈),大家掌声响起:欢迎控制兄(TIMx_CR1)
7 U. D& W9 @$ m) o
261716482798777.png
* d4 Q/ D1 |, D* |- z" V6 C! l
欢迎中断/DMA使能兄(TIMx_DIER):
261721185133335.png
) K, @5 l3 x5 w2 Q6 Q$ E
欢迎预分频器兄(TIMx_PSC):
261723384359882.png
# K1 S" V2 b* H6 D5 i9 d
欢迎自动重装载寄存器兄(TIMx_ARR):
261725582163986.png
. d2 ?' p: Q/ O0 E
好了、、这四位可以在旁边休息了(我们就不介绍了)、、因为我们的重点:库兄要出现了,接下来,用最热烈的掌声欢迎:
首先:有请挂载时钟大神ABP1(为什么要请这位大神呢?因为我们的通用定时器是挂载在这位ABP1的,证据如下)

; [) C4 J9 g7 k5 a' v
261731028577156.png

, f0 p) X  _" m5 v" F2 |2 [9 F: F# T
再者,我们有请第二大神:初始化大神:TIM_TimeBaseInit(为什么是他呢?为什么?究竟是为什么?啊哈、、请看)
% ?+ l. k) X  {+ a: H; @
261735027167733.png
( _3 D# F. k4 ~3 c/ b
看到了吧、、所以请不要怀疑大神的地位哈、、至于参数具体是哪些,大家可以打开#include "stm32f10x_tim.h"哈,在这里就不多说了、、相信大家都是聪明人、
前两位大神出来了,我们还有大神、、哎、、大神无处不在、、来、有请类型中断使能大神
void TIM_ITConfig(TIM_TypeDef* TIMx, u16 TIM_IT, FunctionalState  NewState)
     看到中断、、大家又有想到什么猫腻没??条件发射就是这样炼成的、、没错了、、就是中断优先级设置大神啦、、这个大家应该有印象、我就不细说了哈,没印象的话这位大神可就要躲到某个角落伤心了,
     看到以上大神、、其实还有一位大神没出现、、此大神没出现、、其他大神啥都不是、、对了、就是定时器启动大神
      void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
      好了、、最后,编写中断服务函数,在中断函数里检查中断标志位和清中断标志位,还有你想要做的事,相信大家也是比较熟悉的了、、
   在这里,我们来谈谈时钟的问题、、大家可以看到系统时钟树图里:
9 _5 N5 @0 _* w
261829075919160.png
7 g8 d; `; ^5 e6 N: T5 W0 [( y0 ?
    看到我美丽销魂的涂鸦没、、由于我的系统时钟初始化是36MHZ的、而且设置APB1的预分频系数为2,所以定时器的时钟就为72MHZ,大家可以根据自己的系统时钟设置选择哈、、
到此,我们来总结下使用中断的定时器:
1.开启挂载在ABP1上的TIM3的时钟
2.对定时器进行初始化
3.设置中断类型
4.设置中断优先级
5.开启定时器3
6.编写中断服务函数 看一下参考代码:
  1. void Timer_3_Init(u16 arr,u16 psc)
    3 u+ D& q- Q9 F3 d& ?  L
  2. {
    8 ]1 [+ ^0 x" S" w
  3. + s! v) B: j3 x
  4.       //Tout = (arr + 1) * (psc + 1) / 72;# w7 [. }) F0 `1 Y& i
  5. & r, I6 a$ O( v% Q6 v: `! L! M
  6.       TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    : ]( D6 E  d) ?. V7 W, Q
  7.       NVIC_InitTypeDef NVIC_InitStructure;
    & w4 N1 Z0 l" }
  8. % M& Z- m- C! H7 K& `2 A' }$ M  s( f6 Y
  9.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);                           //1  此数字对应上面的步骤9 \3 |/ L6 V# G) F1 K$ T

  10.   S7 O: ~: O4 c: G+ U" x
  11.       TIM_TimeBaseStructure.TIM_Period = arr;    //这个值在0~65535之间 为16位计数值   //2
    , e6 a- `2 `: v
  12.       TIM_TimeBaseStructure.TIM_Prescaler = psc;# F& ~) C9 b. u* {+ v9 I5 z
  13.       TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;& Q  U! `0 \; t, z  z2 t
  14.       TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    % f8 ^6 z% u& q" }+ ^) `
  15.       TIM_TimeBaseInit(TIM3, & TIM_TimeBaseStructure);
      m& e& P7 a# a  H# b& \

  16. # w2 }, c2 r# N& c$ ^5 V0 ?% b
  17.       TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE );                                    //3
    $ r+ V' D0 i7 r2 R

  18. / r' ^3 ]  i! e6 `( Z7 c1 |
  19.       NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;                                //4
    ) N0 H3 M6 Z7 p7 ^  T  d! Y& h* E: i
  20.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;4 ^) Z, N; U2 T4 z- I# A2 X' C3 ]/ b
  21.       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    * |; J7 X/ w% p* M; L
  22.       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    # u# t& D, s  H8 b8 \% m
  23.       NVIC_Init(&NVIC_InitStructure);
    ; O5 O/ G7 w" |' X

  24. ! f$ E- d4 S5 ]  j1 a, e! a1 ]
  25.     TIM_Cmd(TIM3, ENABLE);                                                         //54 ^% ~% {7 t  ~- j( C/ A
  26. }
    8 s0 X# Q, J7 o. ?
  27. 9 n# F7 ~2 o; ?% @  v
  28. void TIM3_IRQHandler(void)                                                         //6- Q5 v  f* s8 B: K2 g- H
  29. {0 q( V( w4 o1 r4 K' Z% C
  30.     if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)5 T) C2 X  B. Z7 o: w( B. s' s
  31.         {
    ) E' ?) ?$ v- S$ i2 n
  32.         TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    ! F* ^* }  ?0 ]( v( L4 l; g
  33.         LED1 = !LED1;
    " C; y- g$ U+ q% r, j2 a
  34.         }
    0 J9 ~$ |& J! g" }9 u% C) M. Y5 q4 t
  35. }
复制代码
4 j% D1 t" q8 S& R+ C2 b
好了、、说到这里、、通用果然是通用的、、对于所有的通用定时器都是同样的原理、、在这里我们只是实现了简单的定时(值加到某个程度就更新产生中断,通过LED灯显示)、、希望大家多多指教、、本博客比较滑稽、、望大家莫怪哈、、有什么说错的地方请像抓腐败那样提出来哈、、我虚心向您请教、、谢谢大家、、
3 \0 f" v2 u% g, x# G
赞 收藏 评论0 发布时间:2022-1-18 22:49

举报

0个回答

所属标签

相似技术帖

官网相关资源

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