TIM定时器中断理论详解

记住一句话:

定时器就是定时器,作用就是做了一个钟表,时间到了就中断,类似于闹钟到时间就响,这里是到了时间就触发中断

大家一定要带着这句话去理解定时器中断,大方向不要偏,理解自然神。

一、定时器中断原理解释

定时器中断:最简单,最直接的解释

区别于外部中断是电平触发中断

定时器中断,举例来说,一个可以无限计时的设备,设置了计时的方式,还有计时的时间,然后每次到了一个固定的时间,就会执行提前写好的事件。

例如下面这个函数是定时器2定时中断:时间到了就会触发Num变量自增,LED1灯打开

/**
  * 函    数:TIM2中断函数
  * 参    数:无
  * 返 回 值:无
  * 注意事项:此函数为中断函数,无需调用,中断触发后自动执行
  *           函数名为预留的指定名称,可以从启动文件复制
  *           请确保函数名正确,不能有任何差异,否则中断函数将不能进入
  */
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)		//判断是否是TIM2的更新事件触发的中断
	{
		Num ++;												//Num变量自增,用于测试定时中断
		LED1_ON();
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);			//清除TIM2更新事件的中断标志位
															//中断标志位必须清除															
                                                            //否则中断将连续不断地触发,导致主程序卡死
	}
		
}

二、中断时间的计算

根据系统时钟频率、计数周期、预分频器计算出最终的中断时间

三、计数器的三种方式

1. 向上计数模式 (Up Counting Mode)

工作原理

  • 计数器从0开始递增计数,直到达到自动重载寄存器(ARR)的值。
  • 当计数器达到ARR值时,产生一个更新事件,并且计数器重新从0开始计数。

2. 向下计数模式 (Down Counting Mode)

工作原理

  • 计数器从自动重载寄存器(ARR)的值开始递减计数,直到达到0。
  • 当计数器达到0时,产生一个更新事件,并且计数器重新从ARR值开始计数。

3. 中心对齐模式 (Center-Aligned Mode)

工作原理

  • 计数器先从0开始递增计数,直到达到自动重载寄存器(ARR)的一半(即ARR/2),然后开始递减计数,直到回到0。
  • 当计数器达到ARR/2时,产生一个更新事件;当计数器回到0时,再产生一个更新事件。
  • 这种模式实际上是双向计数,因此也称为双边沿计数。

四、时钟源配置

1. 内部时钟源

定时器默认的都是内部时钟源

  • APB1总线上的定时器(如TIM2, TIM3, TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14):
    • 默认时钟源是PCLK1(APB1总线时钟)。
    • 如果APB1预分频器设置为1,则PCLK1等于系统时钟(HCLK)。
    • 如果APB1预分频器设置为其他值(如2或4),则PCLK1会相应地降低。
  • APB2总线上的定时器(如TIM1, TIM8, TIM9, TIM10, TIM11):
    • 默认时钟源是PCLK2(APB2总线时钟)。
    • 如果APB2预分频器设置为1,则PCLK2等于系统时钟(HCLK)。
    • 如果APB2预分频器设置为其他值(如2或4),则PCLK2会相应地降低。

2. 外部时钟源

虽然默认情况下定时器使用内部时钟源,但也可以配置为使用外部时钟源。外部时钟源可以来自以下几个途径:

  • ETR引脚:外部触发输入引脚(External Trigger Input),可以直接作为定时器的时钟源。
  • TIx引脚:定时器的通道输入引脚(例如TI1, TI2, TI3, TI4),可以通过配置用作外部时钟源。
  • ITRx引脚:内部触发输入(Internal Trigger Input),可以是其他定时器的输出或其他内部信号。

3.配置外部时钟源

要配置定时器使用外部时钟源,可以使用以下函数之一:

  • TIM_ETRClockMode1Config:配置外部触发模式1。
  • TIM_ETRClockMode2Config:配置外部触发模式2。
/*配置时钟源*/
	TIM_InternalClockConfig(TIM2);		//选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟

五、定时器中断初始化

timer.c

#include "stm32f10x.h"                  // Device header

/**
  * 函    数:定时中断初始化
  * 参    数:无
  * 返 回 值:无
  */
void Timer_Init(void)
{
	/*开启时钟*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//开启TIM2的时钟
	
	/*配置时钟源*/
	TIM_InternalClockConfig(TIM2);		//选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟
	
	/*时基单元初始化*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定义结构体变量
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;		//时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	//计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;				//计数周期,即ARR的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;				//预分频器,即PSC的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;			//重复计数器,高级定时器才会用到
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);				//将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元	
	
	/*中断输出配置*/
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);						//清除定时器更新标志位
																//TIM_TimeBaseInit函数末尾,手动产生了更新事件
																//若不清除此标志位,则开启中断后,会立刻进入一次中断
																//如果不介意此问题,则不清除此标志位也可
	
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);					//开启TIM2的更新中断
	
	/*NVIC中断分组*/
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);				//配置NVIC为分组2
																//即抢占优先级范围:0~3,响应优先级范围:0~3
																//此分组配置在整个工程中仅需调用一次
																//若有多个中断,可以把此代码放在main函数内,while循环之前
																//若调用多次配置分组的代码,则后执行的配置会覆盖先执行的配置
	
	/*NVIC配置*/
	NVIC_InitTypeDef NVIC_InitStructure;						//定义结构体变量
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;				//选择配置NVIC的TIM2线
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//指定NVIC线路使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;	//指定NVIC线路的抢占优先级为2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			//指定NVIC线路的响应优先级为1
	NVIC_Init(&NVIC_InitStructure);								//将结构体变量交给NVIC_Init,配置NVIC外设
	
	/*TIM使能*/
	TIM_Cmd(TIM2, ENABLE);			//使能TIM2,定时器开始运行
}

/* 定时器中断函数,可以复制到使用它的地方
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}
*/

timer.h

#ifndef __TIMER_H
#define __TIMER_H

void Timer_Init(void);

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值