以下是嵌入式开发系列:STM32学习之旅day09笔记详解

STM32C8T6 TIM定时器中断配置全解析——手把手实现精准定时任务

一、TIM定时器基础概念

TIM(Timer) 是STM32中用于定时、计数、PWM生成的核心外设。通过中断机制,TIM可在特定时间点(如计数器溢出)触发中断,执行用户定义的任务(如数据采集、状态检测等)。

TIM(Timer)定时器
定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时
不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能

根据复杂度和应用场景分为了高级定时器通用定时器基本定时器三种类型 

TIM定时器类型
类型 编号 总线 功能
高级定时器 TIM1、TIM8 APB2 拥有通用定时器全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能
通用定时器 TIM2、TIM3、TIM4、TIM5 APB1 拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能
基本定时器 TIM6、TIM7 APB1 拥有定时中断、主模式触发DAC的功能

STM32C8T6定时器资源

  • 通用定时器:TIM2、TIM3、TIM4(本文以TIM2为例)
  • 高级定时器:TIM1(支持复杂PWM控制)
  • 二、硬件与开发环境

  • 硬件:STM32C8T6最小系统板、LED(PA0引脚)
  • 开发工具:Keil MDK、ST-Link下载器
  • 库支持:STM32标准外设库(StdPeriph Library)
  • 三、TIM2中断配置步骤

    TIM2中断的框图如下:

    TIM2中断的代码流程如下:

    1. 使能时钟

    TIM2挂载在APB1总线,需先开启其时钟:

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    

     

    2. 配置定时器参数

    关键参数:

  • 预分频器(PSC):降低时钟频率。例如系统时钟72MHz,PSC=7199 → 分频后频率=72MHz/(7199+1)=10kHz。
  • 自动重装载值(ARR):设定定时周期。例如ARR=9999 → 定时周期=(9999+1)/10kHz=1秒。
  • 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. 中断未触发

  • 检查NVIC配置是否正确,尤其是中断通道(TIM2_IRQn)
  • 确认中断服务函数名是否为TIM2_IRQHandler
  • 确保TIM_ClearITPendingBit()被调用
  • 2. 定时时间不准确

  • 验证系统时钟是否为72MHz(默认使用内部HSI需额外配置)
  • 检查PSC和ARR计算公式:定时周期 = (ARR+1) * (PSC+1) / 时钟频率
  • 3. 中断频繁触发

  • 检查是否意外修改了ARR或PSC值
  • 确认未使能其他TIM中断源(如捕获/比较中断)
  • 七、总结

            TIM定时器中断是STM32中实现精准定时控制的核心功能。通过合理配置预分频器(PSC)、自动重装载值(ARR)及NVIC中断优先级,开发者可高效完成周期性任务(如数据采集、设备状态检测等),显著降低CPU负载。本文以STM32C8T6的TIM2为例,详细解析了从时钟配置到中断服务函数实现的完整流程。

    在实际开发中,TIM定时器的应用远不止基础定时:

  • PWM输出:驱动电机、调节LED亮度。
  • 输入捕获:精确测量脉冲宽度或频率。
  • 多任务调度:结合多个TIM实现复杂时序控制。
  • 掌握TIM中断技术,能够为嵌入式系统设计带来更高的灵活性与可靠性。


    互动环节

  • 你在项目中用TIM中断做过哪些有趣的应用? 欢迎分享实战经验!
  • 关于TIM中断的配置,你遇到过哪些棘手问题? 评论区留言,一起探讨解决方案!

  • 关注我

  • CSDN博客:小程同学>o<-CSDN博客

  • 作者:小程同学>o\x3C

    物联沃分享整理
    物联沃-IOTWORD物联网 » 以下是嵌入式开发系列:STM32学习之旅day09笔记详解

    发表回复