STM32 定时器中断
介绍
STM32微控制器中的定时器(Timer)是一个强大的外设,用于生成精确的时间延迟、测量时间间隔或生成PWM信号。定时器中断是定时器的一个重要功能,它允许在定时器达到特定条件(如计数器溢出或比较匹配)时触发中断,从而执行特定的任务。
在本教程中,我们将学习如何配置STM32的定时器中断,并通过一个简单的示例来演示如何使用定时器中断实现LED的闪烁。
定时器中断的基本概念
定时器中断的核心思想是:当定时器的计数器达到某个特定值时,触发一个中断请求(IRQ),然后执行相应的中断服务程序(ISR)。STM32的定时器通常有以下几种中断源:
- 更新中断(Update Interrupt):当计数器溢出或下溢时触发。
- 捕获/比较中断(Capture/Compare Interrupt):当计数器值与捕获/比较寄存器的值匹配时触发。
通过配置这些中断源,我们可以实现各种时间相关的功能。
配置STM32定时器中断
1. 选择定时器
STM32系列微控制器通常有多个定时器(如TIM2、TIM3等)。我们需要根据需求选择一个合适的定时器。
2. 配置定时器
配置定时器包括设置预分频器(Prescaler)和自动重装载寄存器(Auto-reload Register)。预分频器用于降低定时器的时钟频率,而自动重装载寄存器决定了计数器的最大值。
// 示例:配置TIM2定时器
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 9999; // 自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler = 7199; // 预分频器
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
3. 使能定时器中断
接下来,我们需要使能定时器的更新中断,并配置NVIC(嵌套向量中断控制器)以处理中断。
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
4. 编写中断服务程序
在中断服务程序中,我们可以执行特定的任务。例如,下面的代码在每次定时器中断时切换LED的状态。
void TIM2_IRQHandler(void) {
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
GPIO_ToggleBits(GPIOC, GPIO_Pin_13); // 切换LED状态
}
}
5. 启动定时器
最后,启动定时器以开始计数。
TIM_Cmd(TIM2, ENABLE);
实际应用案例:LED闪烁
假设我们使用STM32F103C8T6微控制器,并且连接了一个LED到GPIOC的Pin 13。我们可以使用TIM2定时器中断来实现LED的闪烁。
#include "stm32f10x.h"
void TIM2_IRQHandler(void) {
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
GPIO_ToggleBits(GPIOC, GPIO_Pin_13); // 切换LED状态
}
}
int main(void) {
// 初始化GPIOC的Pin 13为输出
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// 配置TIM2定时器
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 9999; // 自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler = 7199; // 预分频器
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// 使能定时器中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// 启动定时器
TIM_Cmd(TIM2, ENABLE);
while (1) {
// 主循环
}
}
提示:在实际应用中,定时器中断可以用于各种任务,如控制电机速度、测量传感器数据、生成PWM信号等。
总结
在本教程中,我们学习了如何配置STM32的定时器中断,并通过一个简单的LED闪烁示例演示了定时器中断的使用。定时器中断是STM32微控制器中非常重要的功能,掌握它可以帮助我们实现各种时间相关的任务。
附加资源与练习
- 练习1:修改代码,使LED以不同的频率闪烁。
- 练习2:尝试使用其他定时器(如TIM3)来实现相同的功能。
- 参考文档:STM32参考手册中的定时器章节,了解更多关于定时器的配置和使用方法。
通过不断练习和探索,你将能够熟练使用STM32的定时器中断功能,并将其应用到更复杂的项目中。