以下是嵌入式开发系列:STM32学习之旅day09笔记详解
STM32C8T6 TIM定时器中断配置全解析——手把手实现精准定时任务
一、TIM定时器基础概念
TIM(Timer) 是STM32中用于定时、计数、PWM生成的核心外设。通过中断机制,TIM可在特定时间点(如计数器溢出)触发中断,执行用户定义的任务(如数据采集、状态检测等)。
TIM(Timer)定时器
定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时
不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型
类型 | 编号 | 总线 | 功能 |
---|---|---|---|
高级定时器 | TIM1、TIM8 | APB2 | 拥有通用定时器全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能 |
通用定时器 | TIM2、TIM3、TIM4、TIM5 | APB1 | 拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能 |
基本定时器 | TIM6、TIM7 | APB1 | 拥有定时中断、主模式触发DAC的功能 |
STM32C8T6定时器资源:
二、硬件与开发环境
三、TIM2中断配置步骤
TIM2中断的框图如下:
TIM2中断的代码流程如下:
1. 使能时钟
TIM2挂载在APB1总线,需先开启其时钟:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
2. 配置定时器参数
关键参数:
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_TimeBaseStruct.TIM_Period = 9999; // ARR值
TIM_TimeBaseStruct.TIM_Prescaler = 7199; // PSC值
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频(默认)
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct);
3. 使能更新中断
开启TIM2的更新中断(计数器溢出时触发):
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
4. 配置NVIC中断优先级
设置TIM2中断通道的优先级并使能:
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; // TIM2中断通道
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; // 子优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
5. 启动定时器
TIM_Cmd(TIM2, ENABLE);
四、中断服务函数实现
在stm32f10x_it.c
中编写中断处理逻辑(示例为LED闪烁):
void TIM2_IRQHandler(void) {
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { // 检测中断标志
GPIO_WriteBit(GPIOA, GPIO_Pin_0,
(BitAction)(1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0))); // 翻转LED
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 必须清除中断标志!
}
}
五、完整代码与主函数
#include "stm32f10x.h"
void TIM2_Init(void) {
// 1. 使能时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 2. 配置TIM2
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_TimeBaseStruct.TIM_Period = 9999;
TIM_TimeBaseStruct.TIM_Prescaler = 7199;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct);
// 3. 使能中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// 4. 配置NVIC
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
// 5. 启动定时器
TIM_Cmd(TIM2, ENABLE);
}
int main(void) {
// 初始化GPIO(PA0接LED)
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
TIM2_Init();
while(1) {
// 主循环可执行其他任务
}
}
六、关键问题排查
1. 中断未触发
TIM2_IRQHandler
TIM_ClearITPendingBit()
被调用2. 定时时间不准确
定时周期 = (ARR+1) * (PSC+1) / 时钟频率
3. 中断频繁触发
七、总结
TIM定时器中断是STM32中实现精准定时控制的核心功能。通过合理配置预分频器(PSC)、自动重装载值(ARR)及NVIC中断优先级,开发者可高效完成周期性任务(如数据采集、设备状态检测等),显著降低CPU负载。本文以STM32C8T6的TIM2为例,详细解析了从时钟配置到中断服务函数实现的完整流程。
在实际开发中,TIM定时器的应用远不止基础定时:
掌握TIM中断技术,能够为嵌入式系统设计带来更高的灵活性与可靠性。
互动环节:
关注我:
CSDN博客:小程同学>o<-CSDN博客
作者:小程同学>o\x3C