通用定时器中断

一.定时器介绍
STM32F1的定时器非常多,由2个基本定时器(TIM6、TIM7)、4个通用定时器(TIM2-TIM5)和2个高级定时器(TIM1、TIM8)组成。基本定时器的功能最为简单,类似于51单片机内定时器。通用定时器是在基本定时器的基础上扩展而来,增加了输入捕获与输出比较等功能。高级定时器又是在通用定时器基础上扩展而来,增加了可编程死区互补输出、重复计数器、带刹车(断路)功能,这些功能主要针对工业电机控制方面。
1.1 通用定时器简介
STM32F1的通用定时器包含一个 16 位自动重载计数器(CNT),该计数器由可编程预分频器(PSC)驱动。STM32F1的通用定时器可用于多种用途,包括测量输入信号的脉冲宽度(输入捕获)或者生成输出波形(输出比较和PWM)等。 使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。STM32F1 的每个用定时器都是完全独立的,没有互相共享的任何资源。

STM32F1的通用定时器TIMx (TIM2-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.输出比较
(6)支持针对定位的增量(正交)编码器和霍尔传感器电路
(7)触发输入作为外部时钟或者按周期的电流管理

二、通用定时器配置步骤
(1)使能定时器时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);	//使能TIM4时钟

(2)初始化定时器参数,包含自动重装值,分频系数,计数方式等

void  TIM_TimeBaseInit(TIM_TypeDef*   TIMx , TIM_TimeBaseInitTypeDef*    TIM_TimeBaseInitStruct);	//第一个参数为使用的定时器,第二个参数为配置结构体的地址

结构体TIM_TimeBaseInitTypeDef的成员

typedef struct{
	uint32_t TIM_Period;            //定时器周期
	uint16_t TIM_Prescaler;         //定时器预分频器
	uint16_t TIM_CounterMode;       //计数模式
	uint16_t TIM_ClockDivision;     //时钟分频
}TIM_TimeBaseInitTypeDef;
TIM_Period 设置了在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_Prescaler 设置了用来作为TIMx时钟频率除数的预分频值
TIM_CounterMode 计数器模式
TIM_CounterMode_Up TIM向上计数
TIM_CounterMode_Down TIM向下计数
TIM_CounterMode_CenterAligned1 TIM中央对齐模式1计数模式
TIM_CounterMode_CenterAligned2 TIM中央对齐模式2计数模式
TIM_CounterMode_CenterAligned3 TIM中央对齐模式3计数模式
TIM_ClockDivision 时钟分割
TIM_CKD_DIV1 tDTS = Tck_tim
TIM_CKD_DIV2 tDTS = 2Tck_tim
TIM_CKD_DIV3 tDTS = 3Tck_tim

定时器定时时间计算公式如下:
Tout= ((per)*(psc+1))/Tclk; //per为周期,psc为预分频,Tclk为时钟分割后的时钟频率

(3)设置定时器中断类型,并使能

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);  //使能或失能指定的TIM中断

NewState为ENABLE(使能)或DISABLE(失能)

TIM_IT 描述
TIM_IT_Update TIM中断源
TIM_IT_CC1 TIM捕获/比较1中断源
TIM_IT_CC2 TIM捕获/比较2中断源
TIM_IT_CC3 TIM捕获/比较3中断源
TIM_IT_CC4 TIM捕获/比较4中断源
TIM_IT_Trigger TIM触发中断源

(初学一般使用TIM_IT_Update较多)

(4)设置定时器中断优先级,使能定时器中断通道
NVIC初始化库函数是NVIC_Init();
(5)开启定时器

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);	//NewState为ENABLE(使能)或DISABLE(失能)

(6)编写定时器中断服务函数

void TIM4_IRQHandler(void){
	if(TIM_GetITStatus(TIM4,TIM_IT_Update)){
		//添加处理事件
	}
	TIM_ClearITPendingBit(TIM4,TIM_IT_Update); 	//清除中断标志
}
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT); 检查中断发生与否
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT); 清除中断标志

三、总结写法如下

/*定时器配置函数
参数:pre为定时器周期,psc为预分频数
返回值:void
功能:配置并开启定时器
*/
void TIM4_Init(u16 pre,u16 psc){
	TIM_TimeBaseInitTypeDef TIM_InitStructure;		//定时器配置结构体
	NVIC_InitTypeDef NVIC_InitStructure;	//中断优先级配置结构体
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);	//使能TIM4的时钟

	TIM_InitStructure.TIM_Period = pre;
	TIM_InitStructure.TIM_Prescaler = psc;
	TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;	

	TIM_TimeBaseInit(TIM4,&TIM_InitStructure);	//定时器初始化

	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);	//使能定时器
	TIM_ClearITPendingBit(TIM4,TIM_IT_Update);	//清除触发标志,避免开启误触发

	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;	//配置中断源
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;	//主优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;	//响应优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	//使能中断
	NVIC_Init(&NVIC_InitStructure);	//中断初始化
	TIM_Cmd(TIM4,ENABLE);	//开启定时器
}

/*中断函数
返回值:void
功能:执行中断事件
*/
void TIM4_IRQHandler(void){	
	if(TIM_GetITStatus(TIM4,TIM_IT_Update)){
		//添加事件
	}
	TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}
发布了8 篇原创文章 · 获赞 6 · 访问量 1168

猜你喜欢

转载自blog.csdn.net/weixin_44762713/article/details/103857514