STM32F4定时器 -- 定时中断

1. 定时器简介

STM32F4的定时器分布如下:
这里写图片描述
- 其中基本定时器包括TIM6、TIM7,其结构最简单,也具有最基本的定时功能,一是用于基本定时、产生时基、二是用于驱动DAC数模转换器。
- 其中通用定时器包括TIME2-TIME5,TIME9-TIME14共10个;通用定时器除了包含基本定时器的功能外还有输入捕获、输出比较和PWM功能等。
- 其中高级定时器包括TIM1、TIM8;
定时器的相关常用寄存器功能如下:

1.1 时钟源选择寄存器(TIMx_SMCR)

定时器的时钟源有4个:
- 内部时钟(CK_INT)
- 外部时钟模式1:外部输入脚(TIx)
- 外部时钟模式2:外部触发输入(ETR),仅适用于TIM2、TIM3、TIM4
- 内部触发输入(ITRx):使得A定时器作为B定时器的预分频器(A为B提供时钟)
这是通过设置TIMx_SMCR的相关位来选择的。其中内部时钟(CK_INT)来自于APB1或APB2总线。

1.2 预分频寄存器(TIMx_PSC)

该寄存器用于对时钟进行分频,然后提供给计数器,作为计数器的时钟。
这里写图片描述
其中16位空间存储分频系数。

1.3 定时器计数寄存器(TIMx_CNT)

它存储了定时器当前的计数值。

1.4 自动重装载寄存器(TIMx_ARR)

该寄存器在物理结构上对应着2个寄存器,一个是程序员可以操作的,另一个是看不到且不能操作的ARM把它叫做影子寄存器。实际上真正起作用的是影子寄存器。
根据 TIMx_CR1 寄存器中 APRE 位的设置: APRE=0 时,预装载寄存器的内容可以随时传送到影子寄存器,此时 2 者是连通的;而 APRE=1 时,在每一次更新事件(UEV)时,才把预装载寄存器( ARR) 的内容传送到影子寄存器。
这里写图片描述

1.5 DMA/中断使能寄存器(TIMx_DIER)

这里写图片描述
这里我们只用最后一位:更新中断使能(UIE:update interrupt enable),改为置1用来允许由更新事件产生的中断。

1.6 控制寄存器1(TIMx_CR1)

这里写图片描述
简单应用中,我们只需要使用最后一位:计数器使能位(CEN:counter enable),改为必须置1才能使计数器开始计数。

1.7 状态寄存器(TIMx_SR)

该寄存器用来标记当前定时器相关的各种事件/中断是否发生。
这里写图片描述

2. 库函数操作实例

接下来我们使用定时器产生定时中断,根据配置定时器的实际步骤,以TIM3为例解析配置过程。
定时器相关的库函数主要集中在固件库文件 stm32f4xx_tim.h 和 stm32f4xx_tim.c 文件中。 定时器配置步骤如下:

2.1 定时器时钟使能

TIM3挂载在APB1下,所以要通过使能APB1总线的使能函数来使能TIM3的时钟源。

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

2.2 初始化定时器参数

配置定时器相关参数。

void TIM_TimeBaseInit(
                    TIM_TypeDef *TIMx,
                    TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct
                    );

第一个参数是指定哪个定时器;
第二个参数是定时器配置参数结构体;

typedef struct{
uint16_t TIM_Prescaler;         //分频系数
uint16_t TIM_CounterMode;       //计数方式(向上、向下、中央对其)
uint16_t TIM_Period;            //自动重载计数值(即定时时间)
uint16_t TIM_ClockDivision;     //时钟分频因子????
uint8_t TIM_RepetitionCounter;
} TIM_TimeBaseInitTypeDef;

实际的:

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  //声明初始化参数结构体变量
TIM_TimeBaseStructure.TIM_Period = 5000;        //以下开始填充
TIM_TimeBaseStructure.TIM_Prescaler =7199;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //执行初始化

2.3 设置TIM3_DIER允许更新中断

库函数TIM_ITConfig用来设置打开中断

void TIM_ITConfig(TIM_TypeDef* TIMx,        //指定哪个定时器
                uint16_t TIM_IT,            //指定中断类型(更新中断、触发中断等等)
                FunctionalState NewState); //使能还是失能

实际的:

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );       //使能更新中断

2.4 设置中断优先级

既然使用中断,就必须设置NVIC,使用NVIC_Init 函数设置。这里就不多讲了,很常用。

2.5 使能定时器

配置好后要使能定时器,使其开始工作,使用TIM_Cmd函数:

void TIM_Cmd(TIM_TypeDef* TIMx,         //指定定时器
            FunctionalState NewState);  //指定状态 

实际的:

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

2.6 编写中断函数

最后还是要编写中断函数来处理定时器产生的相关中断。流程为:
在中断产生后:通过状态寄存器的值来判断此次中断属于什么类型->执行相关操作->清除SR寄存器的中断标志。

  • 读取中断状态的函数:
    ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t);
  • 清除中断状态标志位的函数:
    void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

另外,固件库中还提供了两个函数用来判断定时器的状态和清除定时器状态标志函数:TIM_GetFlagStatus 和 TIM_ClearFlag,它们的作用和上面两个相似,不过它们要先判断中断是否使能,然后再判断中断标志位,而TIM_GetITStatus直接判断中断标志位。


实际的:

if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //判断中断状态
{
//
//do sth here.                                      //执行操作
//
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );        //清除中断标志
  • 6
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值