STM32定时器标准库配置流程及解析

一、定时器分类及特性

STM32定时器分为三类,功能逐级增强:

1.1 基本定时器(TIM6、TIM7)

  • 核心功能:基础定时中断、主模式触发DAC

  • 时基单元:16位计数器、预分频器、自动重装寄存器

  • 计数模式:仅向上计数

  • 时钟源:仅内部时钟(CK_INT)

  • 应用场景:系统基本计时、DAC触发

1.2 通用定时器(TIM2-TIM5)

  • 扩展功能:输入捕获、输出比较、PWM生成、编码器接口

  • 计数模式:向上/向下/中央对齐计数

  • 时钟源:内部时钟、外部时钟(ETR)、其他定时器触发(ITRx)

  • 通道数量:4个独立通道

  • 应用场景:通用控制、传感器接口、PWM输出

1.3 高级定时器(TIM1、TIM8)

  • 增强功能:互补PWM输出、死区控制、刹车功能

  • 重复计数器:支持PWM脉冲数控制

  • 通道数量:6个通道(含互补输出)

  • 应用场景:电机驱动、工业控制

二、配置流程详解

以通用定时器TIM2为例,标准库配置流程如下:

2.1 使能定时器时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

- 高级定时器(TIM1/TIM8)需使RCC_APB2PeriphClockCmd

2.2 配置时钟源

TIM_InternalClockConfig(TIM2);  // 使用内部时钟
// 外部时钟模式1: TIM_ITRxExternalClockConfig(TIM2, TIM_TS_ITR0);
// 外部时钟模式2: TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);

2.3 配置时基单元

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1;        // 预分频器 (72MHz/7200=10kHz)

TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;  // 向上计数模式

TIM_TimeBaseInitStruct.TIM_Period = 10000 - 1;         // 自动重装载值 (10kHz/10000=1Hz)

TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;    // 时钟分频

TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;       // 重复计数器(高级定时器专用)

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);

定时时间计算公式

\[ T = \frac{(PSC+1) \times (ARR+1)}{TIMxCLK} \]

  • 例:72MHz时钟,PSC=7199,ARR=9999 → 定时1秒

2.4 配置中断(如需中断功能)

// 清除更新标志位

TIM_ClearFlag(TIM2, TIM_FLAG_Update);

// 使能更新中断

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

// NVIC配置

NVIC_InitTypeDef NVIC_InitStruct;

NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStruct);

2.5 启动定时器

TIM_Cmd(TIM2, ENABLE);

2.6 中断服务函数

void TIM2_IRQHandler(void) {

    if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) {

        // 用户代码

        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  // 清除中断标志位

    }

}

三、关键结构体解析

3.1 TIM_TimeBaseInitTypeDef

typedef struct {

  uint16_t TIM_Prescaler;         // 预分频值(0-65535)

  uint16_t TIM_CounterMode;       // 计数模式

  uint16_t TIM_Period;            // 自动重装载值(0-65535)

  uint16_t TIM_ClockDivision;     // 时钟分频(TIM_CKD_DIV1/2/4)

  uint8_t TIM_RepetitionCounter;  // 重复计数器(仅高级定时器)

} TIM_TimeBaseInitTypeDef;

3.2 计数模式选项

  • TIM_CounterMode_Up:向上计数(0→ARR)

  • TIM_CounterMode_Down:向下计数(ARR→0)

  • TIM_CounterMode_CenterAligned1/2/3:中央对齐模式

四、定时器时钟树

定时器时钟来源路径:

SYSCLK(72MHz) → AHB Prescaler → APB1/APB2 Prescaler 

→ 定时器时钟(TIMxCLK)
  • APB1外设:最高36MHz,定时器时钟=APB1时钟×2(当APB1分频>1时)

  • APB2外设:最高72MHz,定时器时钟=APB2时钟×2(当APB2分频>1时)

## 五、配置示例(1ms定时中断)

void TIM2_Init_1ms(void) {

    // 1. 使能时钟

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  

    // 2. 配置时基单元

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

    TIM_TimeBaseInitStruct.TIM_Prescaler = 71;       // 72MHz/72=1MHz

    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInitStruct.TIM_Period = 999;         // 1MHz/1000=1kHz → 1ms

    TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;

    TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);

  

    // 3. 配置中断

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    TIM_ClearFlag(TIM2, TIM_FLAG_Update);

  

    // 4. NVIC配置

    NVIC_InitTypeDef NVIC_InitStruct;

    NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;

    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;

    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStruct);

  

    // 5. 启动定时器

    TIM_Cmd(TIM2, ENABLE);

}

六、调试与注意事项

1. 中断标志位清除:必须在中断服务函数中清除标志位

2. 预分频器计算:实际分频系数=PSC值+1

3. 自动重装载:ARR=0时仍会产生中断

4. 影子寄存器:使能ARPE位可实现ARR缓冲更新

5. 多定时器同步:可通过ITRx实现定时器级联

七、定时器应用场景

| 功能 | 配置关键点 | 典型应用 |

| ---------- | ---------------- | ----------- |

| 定时中断 | ARR+PSC配置 | 系统时基 |

| PWM输出 | 比较寄存器(CCRx) | 电机驱动 |

| 输入捕获 | 滤波+边沿检测 | 频率测量 |

| 编码器接口 | TI1/TI2极性配置 | 电机测速 |

| 主从触发 | TRGO信号配置 | ADC同步采样 |

八、常见问题解决

1. 定时器不触发中断

  • 检查NVIC优先级分组配置

  • 确认中断使能位(TIM_ITConfig)

  • 验证时钟使能状态

2. 定时精度偏差

  • 校准系统时钟(HSE_VALUE)

  • 避免使用过低的预分频值

  • 考虑中断服务函数执行时间

3. PWM占空比异常

  • 检查CCRx寄存器配置

  • 确认输出比较模式设置

  • 验证GPIO复用功能配置

STM32定时器分类框图

1.2 通用定时器(TIM2-TIM5)

通用定时器功能框图

  • 扩展功能:输入捕获、输出比较、PWM生成、编码器接口

  • 计数模式:向上/向下/中央对齐计数

  • 时钟源:内部时钟、外部时钟(ETR)、其他定时器触发(ITRx)

  • 通道数量:4个独立通道

  • 应用场景:通用控制、传感器接口、PWM输出

二、配置流程详解

定时器配置流程图

以通用定时器TIM2为例,标准库配置流程如下:

四、定时器时钟树

STM32时钟树结构

定时器时钟来源路径:

SYSCLK(72MHz) → AHB Prescaler → APB1/APB2 Prescaler 

→ 定时器时钟(TIMxCLK)

## 三、关键结构体解析

TIM_TimeBaseInitTypeDef结构体成员

3.1 TIM_TimeBaseInitTypeDef

typedef struct {

  uint16_t TIM_Prescaler;         // 预分频值(0-65535)

  uint16_t TIM_CounterMode;       // 计数模式

  uint16_t TIM_Period;            // 自动重装载值(0-65535)

  uint16_t TIM_ClockDivision;     // 时钟分频(TIM_CKD_DIV1/2/4)

  uint8_t TIM_RepetitionCounter;  // 重复计数器(仅高级定时器)

} TIM_TimeBaseInitTypeDef;