STM32F4X 定时器中断

什么是定时器

定时器(Timer)最基本的功能就是定时,比如定时翻转LED灯,定时向串口发送数据等。除此之外,定时器还可以跟GPIO结合使用,利用定时器产生PWM波形,利用定时器捕捉电平信号等。本章先来讲解定时器的最基本的用法,定时功能。

STM32F4X 定时器分类

STM32F4X将定时器分成3类,分别是基本定时器,通用定时器和高级定时器,不同类型的定时器功能不同。下图是STM32F4X的定时器分类以及功能。本章会用基本定时器,也就是TIM6或者TIM7来进行讲解。
在这里插入图片描述

有关定时器的概念

预分频(PSC)

定时器想要工作,首先要用时钟,时钟的作用是给定时器一个时基,让定时器按照这个时基单元进行计数。在STM32F4中,定时器是的时钟源是APB时钟。比如APB的时钟是84MHz,那么定时器的时钟就是84MHz。而预分频的作用是对定时器的时钟源进一步细分,得到用户想要的时钟频率。比如用户觉得84MHz的时钟频率太高了,想得到一个42MHz的频率,就可以往定时器的预分频寄存器里面写1(注意:定时器的预分频寄存器会将预分频系数自动加1),就会得到42MHz的频率。
在这里插入图片描述
在这里插入图片描述
要注意的时定时器的时钟源会根据硬件自动选择,具体如下图所示。
高级定时器timer1, timer8以及通用定时器timer9, timer10, timer11的时钟来源是APB2总线。
通用定时器timer2 ~ timer5,通用定时器timer12 ~ timer14以及基本定时器timer6,timer7的时钟来源是APB1总线。

在这里插入图片描述

自动重装载值(ARR)

上面的预分频寄存器设置了定时器的计数频率,那么用户要怎样才能得到想要的定时值呢,这就需要自动重装载值寄存器了。自动重装载寄存器的作用是设置定时器的溢出值,当定时器计数超过自动重装载值寄存器里面值的时候,就会产生一个溢出中断。下面举个例子说明一下。
比如现在需要一个500ms的定时器,APB时钟是84MHz,我们可以这样设置。
预分频系数设置为8399,即定时器的计数频率为84Mhz / 8400 = 10KHZ,定时器每隔10KHz计一次数,也就是0.1ms记一次数,想要得到500ms的定时时间,只需要往自动重装载值寄存器里面写4999即可,也就是0.1*5000 = 500ms。
定时器的计算公式如下:
Tout = (1 / (Tclk / (psc + 1))) * (arr + 1)
Tout:定时器溢出值
Tclk:定时器时钟频率
psc:定时器预分频值
arr:自动重装载值

STM32F4X定时器例程

定时器相关函数

/*
定时器初始化函数
TIMx:定时器索引
TIM_TimeBaseInitStruct:定时器初始化结构体
*/
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)

/*
定时器中断使能函数
TIMx:定时器索引
TIM_IT:定时器中断类型
NewState:定时使能
*/
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)


/*
定时器获取中断状态函数
TIMx:定时器索引
TIM_IT:定时器中断类型
返回值:定时器中断状态
*/
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)


/*
定时器清除中断状态函数
TIMx:定时器索引
TIM_IT:定时器中断类型
*/
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)

定时器例程

该例程是使用定时器7产生一个500ms的中断

#include "timer.h"

void bsp_timer_init(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	RCC_ClocksTypeDef RCC_Clocks;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7,ENABLE); // 使能定时器7时钟
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; 
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
	TIM_TimeBaseInitStruct.TIM_Period = 4999; // 重装值为5000 500ms中断一次
	TIM_TimeBaseInitStruct.TIM_Prescaler = 8399; // 预分配值为8400 即84000000/8400 = 10KHZ 0.1ms计一次书
	TIM_TimeBaseInit(TIM7,&TIM_TimeBaseInitStruct); // 初始化定时器7
	
	NVIC_InitStruct.NVIC_IRQChannel = TIM7_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority  = 2;
	NVIC_Init(&NVIC_InitStruct);  // 配置定时器7 NVIC中断
	
	TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE); // 使能更新中断
	TIM_Cmd(TIM7,ENABLE); // 使能定时器7
	
	
}


void TIM7_IRQHandler(void)
{
	if(TIM_GetFlagStatus(TIM7,TIM_IT_Update) == SET) // 判断是否为定时器7更新中断
	{
		printf("%s\r\n",__func__);
		TIM_ClearITPendingBit(TIM7,TIM_IT_Update);	// 清除定时器7更新中断
	}
	
}

打开Xcom串口助手,勾选时间戳功能,可以看到串口每隔500ms就进入中断并打印信息。
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值