STM32自学笔记(四)定时器中断

定时器离不开中断,前置技能——中断若没有加点的话,可以去下面的链接看下

传送门:https://blog.csdn.net/pmj110119/article/details/86748016

TIM功能简介

STM32F1的通用 TIMx (TIM2、TIM3、TIM4 和 TIM5)定时器功能包括:

  1. 16位自动装载计数器(TIMx_CNT

  2. 16位可编程预分频器(TIMx_PSC),分频系数为1~65535之间任意数值。

  3. 4个独立通道(TIMx_CH1~4),这些通道可以用来作为:

    A. 输入捕获

    B. 输出比较

    C. PWM生成

    D. 单脉冲模式输出

  4. 可使用外部信号(TIMx_ETR)控制定时器与定时器互连(用1个定时器控制另外一个定时器)的同步电路

  5. 如下事件发生时产生中断/DMA:

    A. 更新:计数器溢出,计数器初始化

    B. 触发事件:计数器启动、停止、初始化

    C. 输入捕获

    D. 输出比较

    E. 增量编码器和霍尔传感器电路

    F. 触发输入作为外部时钟或者按周期的电流管理

配置定时器

1)TIMx时钟使能

TIM3 是挂载在 APB1 之下,所以我们通过 APB1 总线下的使能使能函数来使能 TIM3。调用的函数是:

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能 

2)初始化定时器

参数结构体类型为 TIM_TimeBaseInitTypeDef,初始化函数为 TIM_TimeBaseInit范例如下:

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure; 
  TIM_TimeBaseStructure.TIM_Period = 5000;                    //设置重载计数周期值:5000
  TIM_TimeBaseStructure.TIM_Prescaler =7199;                  //设置分频系数:7199
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //时钟分频因子:时钟分割
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //设置计数方式:向上计数
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);             //初始化TIM3

3)定时器中断使能

接下来进行定时器中断使能,通过 TIM_ITConfig函数实现

第一个参数是选择定时器号,取值 TIM1~TIM17.

第二个参数指明定时器中断的类型。包括更新中断 TIM_IT_Update,触发中断  TIM_IT_Trigger,以及输入捕获中断等等

        (本章代码都以更新中断为例)

第三个参数填 ENABLE就好

例如使能TIM3的更新中断,格式为:

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); 

4)NVIC中断优先级设置

不加赘述,直接贴代码

  NVIC_InitTypeDef NVIC_InitStructure;   
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;             //TIM3 中断  
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   //先占优先级 0 级  
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;          //从优先级 3 级  
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //IRQ 通道被使能  
  NVIC_Init(&NVIC_InitStructure);                             //初始化 NVIC 寄存器

5)定时器使能

配置好定时器后,就可以开启定时器了。通过 TIM_Cmd函数使能定时器

TIM_Cmd(TIM3, ENABLE);  //使能 TIMx 外设 

这个函数很简单,一看便懂。

6)编写中断服务函数

定时器中断产生后,需要通过中断服务函数来处理这次中断。

首先,判断定时器是否发生更新(溢出)中断,方法为

 if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){} 

在这个 if 里面进行这次中断的处理。

中断处理函数结束前,需要清除中断标志位,函数调用格式如下

  TIM_ClearITPendingBit(TIM3, TIM_IT_Update  ); 

中断溢出时间的计算

计算公式

首先申明几个参数:arr为自动重装值;psc为时钟预分频数 ,这两个由我们用户指定

Tclk为 TIM 的输入时钟频率(TIM3为72 Mhz)

溢出时间计算公式为:Tout= ((arr+1)*(psc+1))/Tclk

定时500ms范例

指定 arr=4999;psc=7199

则 Tout= ((4999+1)*( 7199+1))/72=500000us=500ms。

定时器配置的完整代码

可写为 timer.c文件,直接调用

  #include "timer.h" 
  #include "led.h" 
  //通用定时器 3 中断初始化 
  //这里时钟选择为 APB1 的 2 倍,而 APB1 为 36M 
  //arr:自动重装值。 
  //psc:时钟预分频数 
  //这里使用的是定时器 3! 
  void TIM3_Int_Init(u16 arr,u16 psc) 
  {     
      TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  
      NVIC_InitTypeDef NVIC_InitStructure;  
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //①时钟 TIM3 使能
      
      //定时器 TIM3 初始化  
      TIM_TimeBaseStructure.TIM_Period = arr;    //设置自动重装载寄存器周期的值    
      TIM_TimeBaseStructure.TIM_Prescaler =psc;  //设置时钟频率除数的预分频值  
      TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割  
      TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM 向上计数 
      TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);          //②初始化 TIM3   
      TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );             //③允许更新中断  
  ​
      //中断优先级 NVIC 设置  
      NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;        //TIM3 中断  
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级 0 级  
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //从优先级 3 级  
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;      //IRQ 通道被使能  
      NVIC_Init(&NVIC_InitStructure);                         //④初始化 NVIC 寄存器 
      //⑤使能 TIM3 
      TIM_Cmd(TIM3, ENABLE);                                      
  } 
  //定时器 3 中断服务程序⑥ 
  void TIM3_IRQHandler(void)   //TIM3 中断 
  {  
      if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查 TIM3 更新中断发生与否    
      {   
          TIM_ClearITPendingBit(TIM3, TIM_IT_Update  ); //清除 TIM3 更新中断标志    
          LED1=!LED1;                                   //本次中断执行的代码
      } 
  }

 

你可能感兴趣的:(stm32自学笔记,stm32,单片机,嵌入式)