STM32定时器部分详解及定时中断实现

一.定时中断(概念部分)

定时中断主要包含两种中断一种是更新中断还有一种是输入捕获中断

  1. 更新中断:更新中断通常用于定时器的基本定时功能。当定时器计数器溢出并重新从零开始计数时,会触发更新中断。你可以配置定时器的计数周期和预分频器来控制定时器的计时时间。更新中断允许你执行一些操作,比如更新某些变量、执行周期性任务或控制外部设备。

  2. 输入捕获中断:输入捕获中断用于测量外部事件的时间间隔。当外部事件触发定时器捕获通道时,输入捕获中断可以捕获定时器的当前值,并允许你计算时间间隔或频率等参数。

定时器定时中断是一种常见的应用场景,它允许你在一定时间间隔内触发一个中断服务程序。在STM32微控制器中,你可以使用定时器外设来实现定时中断。以下是一般的步骤:

  1. 选择定时器:首先,选择一个可用的定时器。STM32系列通常配备有多个不同类型的定时器,如TIM1、TIM2、TIM3等,具体型号取决于你的微控制器型号。每个定时器都有不同的功能和性能。

  2. 配置定时器:配置定时器的预分频器和计数周期,以确定定时中断的触发时间。你可以使用寄存器来配置这些参数。例如,你可以设置预分频器来控制时钟频率的分频,以及设置计数周期以确定定时中断触发的时间。

  3. 配置中断:使能定时器的更新中断。通常,你需要配置定时器控制寄存器,设置更新中断使能位。

  4. 编写中断服务程序:编写中断服务程序(ISR),它是一个特殊的函数,当定时器中断被触发时将被执行。这个中断服务程序可以执行你希望在定时中断时执行的操作。确保在ISR中处理中断标志,以便在中断处理完成后清除标志,以允许下一个中断触发。

  5. 启动定时器:启动定时器以开始定时中断的运行。你需要设置定时器控制寄存器中的启动位。

  6. 等待中断触发:一旦定时器计数达到你配置的计数周期,定时器将触发更新中断,然后中断服务程序将被执行。

  7. 中断处理完毕:确保在中断服务程序中执行必要的操作,并在处理完毕后返回。

这是一个通用的流程,具体的代码和配置会依赖于你的STM32微控制器型号和开发环境。你需要查看特定型号的参考手册和技术文档,以获取详细的配置和编程示例。

二.代码部分(参考江科大)

void Timer_Init(void)//初始化定时器
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	TIM_InternalClockConfig(TIM2);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;//自动重装值,范围为0到65535
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//预分频值,范围为0到65535
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2, ENABLE);
}

定时器溢出频率公式:72mhz/(psc+1)/(arr+1)注意1mhz后面6个零

预分频值(psc):就是将你使用的时钟频率以预分频系数进行分割。举个例子:stm32的内部时钟频率是72mhz,如果预分频系数是72那么72mhz/72就是1mhz,就是定时器1s内会计数1000000次。

自动重装值(arr):就是当定时器的值计数到这个值之后,就会溢出产生中断类似于更新中断,然后重新装载为0,我们继续以上面的例子为例如果我们要定时10毫秒,由于现在是1s内计数1000000次所以我们就要将arr定为10000。

更改定时器的频率可以自动重装值给小点不改变预分频值,这样就是以一个频率计一个比较少的数,如果预分频值给小一点自动重装值不变,这样就是以高的频率计一个数。

中断代码部分

void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
           
          //加上中断要执行的函数
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

外部时钟部分

以上应用于内部时钟,接下来我们用外部时钟,使用ETR外部时钟外部时钟模式2

代码

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2, ENABLE);
}

作者:2301_79648779

物联沃分享整理
物联沃-IOTWORD物联网 » STM32定时器部分详解及定时中断实现

发表评论