STM32定时器

STM32 的定时器(Timer)是 MCU 内部的一个重要外设,广泛用于精确计时、事件计数、PWM 生成、输入捕获等功能。我们可以把定时器比喻成一个精确的电子时钟,它可以计时、闹钟、秒表、定时提醒,甚至可以控制电灯亮灭、马达转速等外部设备。


1. STM32 定时器的分类

STM32 的定时器主要分为以下几类,它们在功能和用途上有所不同:

定时器类型典型型号主要功能
高级定时器TIM1、TIM8具有高级 PWM、死区控制,适合电机控制
通用定时器TIM2、TIM3、TIM4、TIM5、TIM9、TIM10、TIM11、TIM12、TIM13、TIM14常规计时、PWM 输出、输入捕获、事件计数
基本定时器TIM6、TIM7仅用于定时,不支持输入捕获/PWM,多用于DAC 触发
低功耗定时器LPTIM1、LPTIM2低功耗应用(如休眠唤醒、RTC 相关)
独立看门狗(IWDG)IWDG防止程序卡死,自动复位 MCU
窗口看门狗(WWDG)WWDG检测代码异常、周期性喂狗,超时复位

其中,高级定时器(如 TIM1、TIM8)通常用于复杂的 PWM 控制,比如电机驱动,而通用定时器(如 TIM2-TIM5)则更常用于常规的 PWM、输入捕获、定时中断等功能。


2. 定时器的基本工作原理

2.1 定时器的核心组成

可以将 STM32 的定时器想象成一个电子秒表,它主要包含以下几个核心部件:

  • 时钟源(Clock Source):提供定时器计数的时钟,通常是 APB1 或 APB2 时钟(经过分频)。
  • 预分频器(Prescaler, PSC):用来调整计数的速度(相当于秒表的快慢调节)。
  • 计数器(Counter, CNT):核心组件,记录时间的流逝(类似秒表的读数)。
  • 自动重装载值(ARR,Auto Reload Register):设置定时器的最大计数值,计数到该值后可以自动清零触发中断
  • 比较寄存器(CCR,Capture/Compare Register):用于 PWM 和输入捕获。

官方手册中的通用定时器结构图如下:

高级定时器的结构图如下:

基本定时器的结构如下:


2.2 计数模式

STM32 定时器有 3 种常见的计数模式:

  1. 向上计数模式(Up Mode):从 0 计数到 ARR,然后清零重新计数。
  2. 向下计数模式(Down Mode):从 ARR 计数到 0,然后重新计数。
  3. 中心对齐模式(Center-aligned Mode):先向上计数到 ARR,然后反向计数到 0(适用于 PWM)。

计数模式示意图:

Up Mode:    0 → 1 → 2 → … → ARR → 0 → 1 → ...
Down Mode:  ARR → … → 2 → 1 → 0 → ARR → ...
Center Mode: 0 → 1 → … → ARR → … → 1 → 0 → ...

3. STM32 定时器的主要功能

3.1. 定时中断

定时器最常见的功能是定时触发中断。比如,我们可以让 STM32 每隔 1 秒 触发一次中断,在中断里执行一些任务(比如控制 LED 闪烁)。

示例:配置 TIM2 每秒触发一次中断

void Timer2_Init(void) {
    __HAL_RCC_TIM2_CLK_ENABLE(); // 使能 TIM2 时钟
    TIM_HandleTypeDef htim2;
    
    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 7200 - 1;  // 预分频 7200(假设 APB1 时钟 72MHz)
    htim2.Init.Period = 10000 - 1;    // 计数 10000 次(总共 1 秒)
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    
    HAL_TIM_Base_Init(&htim2);
    HAL_TIM_Base_Start_IT(&htim2); // 启用中断模式
}

3.2. PWM 输出

定时器可以用来生成 PWM(脉冲宽度调制)信号,常用于控制舵机、电机,或者调节 LED 亮度。

示例:TIM2 生成 50Hz PWM 信号

void PWM_Init(void) {
    TIM_HandleTypeDef htim2;
    TIM_OC_InitTypeDef sConfigOC;
    
    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 720-1;   // 预分频 720
    htim2.Init.Period = 2000-1;     // PWM 频率 50Hz(=72MHz / 720 / 2000)
    HAL_TIM_PWM_Init(&htim2);
    
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 150; // 设定 PWM 占空比(可调)
    HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
    
    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
}

3.3. 输入捕获

输入捕获(Input Capture)用于测量外部信号的频率或脉宽,比如超声波测距红外遥控解码等。

📌 示例:使用 TIM1 捕获外部信号

void Input_Capture_Init(void) {
    TIM_HandleTypeDef htim1;
    TIM_IC_InitTypeDef sConfigIC;
    
    htim1.Instance = TIM1;
    htim1.Init.Prescaler = 72-1;   // 预分频 72(假设 72MHz 时钟)
    htim1.Init.Period = 0xFFFF;    // 16-bit 计数
    HAL_TIM_IC_Init(&htim1);
    
    sConfigIC.ICPolarity = TIM_ICPOLARITY_RISING;
    sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
    sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
    HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1);
    
    HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1);
}

3.4. 事件计数

定时器还能用来计数外部信号的脉冲,适用于 计步器、编码器 等应用。


4. 总结

STM32 定时器就像一个可编程的电子计时器,可以用来:

定时触发事件(定时中断)
产生 PWM 信号(控制 LED、舵机、电机)
测量脉冲信号(输入捕获,用于超声波测距等)
计数外部事件(编码器、电机测速)

上一篇
下一篇