一、定时器概述

1. 软件定时的局限

软件定时通常使用 CPU 死等的方式实现,例如循环执行空指令或等待计数变量变化。

这种方式的问题很明显:

问题 说明
延时不精准 编译优化、主频变化、中断打断都会影响延时
浪费 CPU CPU 在等待期间不能高效处理其他任务
可维护性差 延时时间和代码执行环境强相关

因此,在 STM32 中更推荐使用硬件定时器实现精准时基。

2. 定时器定时原理

定时器的核心就是计数器。

定时器使用一个精准时钟作为时基,通过硬件计数的方式实现定时。当计数器达到设定条件后,可以产生更新事件、中断或 DMA 请求。

可以简化理解为:

定时器时钟 -> 预分频器 -> 计数器 -> 溢出/更新事件 -> 中断或触发输出

定时器的优势是:计数过程由硬件完成,CPU 只需要配置参数并处理中断或事件。

3. STM32 定时器分类

STM32 中的定时器可以分为常规定时器、专用定时器和内核定时器。

分类 典型外设
基本定时器 TIM6、TIM7
通用定时器 TIM2、TIM3、TIM4、TIM5 等
高级定时器 TIM1、TIM8
专用定时器 独立看门狗、窗口看门狗、RTC、低功耗定时器
内核定时器 SysTick

不同 STM32 系列的定时器数量和功能会有差异,实际开发时应参考对应芯片数据手册或开发板开发指南。

4. 基本、通用、高级定时器区别

类型 主要功能
基本定时器 无输入输出通道,常用作时基
通用定时器 有多路独立通道,可用于输入捕获、输出比较、PWM,也可作时基
高级定时器 具备通用定时器功能,还支持互补输出、死区控制、刹车输入等

高级定时器常用于电机控制、数字电源等对 PWM 输出和安全保护要求较高的场景。

二、基本定时器

1. 基本定时器简介

基本定时器常见于 TIM6TIM7

主要特性:

  • 16 位递增计数器,计数范围 0 ~ 65535

  • 16 位预分频器,分频系数 1 ~ 65536

  • 可用于触发 DAC

  • 在更新事件,也就是计数器溢出时,可产生中断或 DMA 请求

基本定时器没有输入输出通道,因此最常见用途是作为系统中的基础时间片或周期中断源。

2. 基本定时器框图理解

基本定时器主要由三部分组成:

模块 作用
时钟源 为定时器提供计数时钟
控制器 控制定时器启动、停止、更新事件等
时基单元 包括预分频器、计数器、自动重装载寄存器

简化结构:

TIMxCLK -> PSC预分频器 -> CNT计数器 -> ARR自动重装载 -> 更新事件

其中:

  • PSC:预分频寄存器

  • CNT:当前计数器

  • ARR:自动重装载寄存器

3. 计数模式和溢出条件

定时器常见计数模式如下:

计数模式 溢出或更新条件
递增计数模式 CNT == ARR
递减计数模式 CNT == 0
中心对齐模式 CNT == ARR - 1CNT == 1

基本定时器通常使用递增计数模式。

4. 溢出时间计算

定时器溢出时间由定时器时钟、预分频值和自动重装载值决定。

基本公式:

Tout = (PSC + 1) * (ARR + 1) / TIMxCLK

其中:

  • Tout:定时器溢出时间,单位为秒

  • PSC:预分频寄存器的值

  • ARR:自动重装载寄存器的值

  • TIMxCLK:定时器输入时钟频率

如果希望定时器每 500 ms 产生一次更新中断,就需要根据 TIMxCLK 反推合适的 PSCARR

5. 基本定时器中断配置步骤

使用 HAL 库配置基本定时器中断,可以按以下流程理解:

  1. 配置定时器基础工作参数:HAL_TIM_Base_Init()

  2. 完成 MSP 底层初始化:HAL_TIM_Base_MspInit()

  3. 使能更新中断并启动计数器:HAL_TIM_Base_Start_IT()

  4. 设置中断优先级并使能中断:HAL_NVIC_SetPriority()HAL_NVIC_EnableIRQ()

  5. 编写中断服务函数:TIMx_IRQHandler(),并调用 HAL_TIM_IRQHandler()

  6. 编写定时器更新中断回调函数:HAL_TIM_PeriodElapsedCallback()

中断调用链可以理解为:

TIMx_IRQHandler() -> HAL_TIM_IRQHandler() -> HAL_TIM_PeriodElapsedCallback()

三、通用定时器

1. 通用定时器简介

以 STM32F1 为例,通用定时器包括 TIM2TIM3TIM4TIM5

主要特性:

  • 16 位递增、递减、中心对齐计数器,计数范围 0 ~ 65535

  • 16 位预分频器,分频系数 1 ~ 65536

  • 可用于触发 DAC、ADC

  • 在更新事件、触发事件、输入捕获、输出比较时可产生中断或 DMA 请求

  • 具备 4 个独立通道

  • 支持输入捕获、输出比较、PWM、单脉冲模式

  • 支持外部信号控制定时器

  • 支持多个定时器互连

  • 支持编码器和霍尔传感器接口

相比基本定时器,通用定时器的重点是“通道”。有了通道,定时器就可以和外部 IO 信号产生联系。

2. 通用定时器框图理解

通用定时器可以分为以下功能模块:

模块 作用
时钟源 决定计数器计数节拍
控制器 控制定时器运行模式
时基单元 完成分频、计数、自动重装载
输入捕获 捕获外部输入信号的时间点
捕获/比较公共部分 连接输入捕获和输出比较
输出比较 根据比较值控制输出状态

通用定时器既可以用作普通定时中断,也可以用来产生 PWM、测量脉宽、统计外部脉冲等。

3. 计数器时钟源

通用定时器常见时钟源包括:

时钟源 说明 关键配置
内部时钟 CK_INT 来自外设总线 APB 提供的时钟 TIMx_SMCR.SMS = 000
外部时钟模式 1 来自定时器通道 1 或通道 2 引脚信号 TIMx_SMCR.SMS = 111
外部时钟模式 2 来自可复用为 TIMx_ETR 的 IO 引脚 TIMx_SMCR.ECE = 1
内部触发输入 ITRx 用于与其他通用/高级定时器级联 参考芯片参考手册

外部时钟和内部触发输入使定时器可以参与更复杂的同步控制,例如定时器级联、外部脉冲计数等。

四、通用定时器 PWM 输出

1. 输出比较与 PWM 原理

PWM 输出依赖输出比较功能。

定时器计数器 CNT 按时基不断变化,捕获/比较寄存器 CCRx 保存比较值。当 CNTCCRx 的关系满足某种条件时,输出电平发生变化,从而形成 PWM 波形。

PWM 的两个关键参数:

参数 决定因素
周期或频率 ARR 决定
占空比 CCRx 决定

常见计算关系:

PWM频率 = TIMxCLK / ((PSC + 1) * (ARR + 1))
占空比 = CCRx / (ARR + 1)

2. PWM 模式

通用定时器常见 PWM 模式包括:

模式 理解方式
PWM 模式 1 在不同计数区间输出有效/无效电平
PWM 模式 2 与模式 1 的有效电平区间相反

实际输出电平还与极性配置有关。配置 PWM 时,除了模式本身,还需要关注通道极性、预装载、GPIO 复用等参数。

3. PWM 输出配置步骤

使用 HAL 库配置 PWM 输出时,典型流程如下:

  1. 配置定时器基础工作参数:HAL_TIM_PWM_Init()

  2. 完成 PWM MSP 初始化:HAL_TIM_PWM_MspInit()

  3. 配置 PWM 模式、比较值等:HAL_TIM_PWM_ConfigChannel()

  4. 使能输出并启动计数器:HAL_TIM_PWM_Start()

  5. 根据需要修改比较值控制占空比:__HAL_TIM_SET_COMPARE()

  6. 根据需要使能通道预装载:__HAL_TIM_ENABLE_OCxPRELOAD()

如果 PWM 引脚没有输出,优先检查 GPIO 是否配置为正确的复用功能。

五、通用定时器输入捕获

1. 输入捕获原理

输入捕获用于记录外部信号边沿到来时的计数器值。

当配置好的边沿到来时,当前 CNT 的值会被锁存到对应的 CCRx 寄存器中。通过比较两次捕获值,就可以计算周期、频率或脉宽。

测量高电平脉宽时,可以理解为:

高电平计数个数 = 溢出次数 * (ARR + 1) + 捕获差值

高电平期间的计数个数可以表示为:

高电平期间计数个数 = N * (ARR + 1) + CCRx2

其中 N 表示高电平期间发生的定时器溢出次数。

2. 输入捕获配置步骤

使用 HAL 库配置输入捕获时,典型流程如下:

  1. 配置定时器基础工作参数:HAL_TIM_IC_Init()

  2. 完成输入捕获 MSP 初始化:HAL_TIM_IC_MspInit()

  3. 配置输入通道映射、捕获边沿等:HAL_TIM_IC_ConfigChannel()

  4. 设置中断优先级并使能中断:HAL_NVIC_SetPriority()HAL_NVIC_EnableIRQ()

  5. 使能定时器更新中断:__HAL_TIM_ENABLE_IT()

  6. 使能捕获、捕获中断和计数器:HAL_TIM_IC_Start_IT()

  7. 编写中断服务函数:TIMx_IRQHandler(),并调用 HAL_TIM_IRQHandler()

  8. 编写更新中断和捕获回调函数:HAL_TIM_PeriodElapsedCallback()HAL_TIM_IC_CaptureCallback()

输入捕获常用于测量按键脉宽、外部 PWM 周期、超声波模块回波时间等。

六、通用定时器脉冲计数

通用定时器也可以使用外部输入信号作为计数时钟,实现脉冲计数。

1. 脉冲计数原理

当定时器使用外部时钟模式时,外部引脚输入的脉冲会驱动计数器递增。此时定时器不再主要依赖内部时钟计时,而是用于统计外部脉冲个数。

典型用途:

  • 统计外部方波脉冲数量

  • 测量转速传感器脉冲

  • 统计编码器相关输入信号

2. 脉冲计数配置步骤

使用 HAL 库配置脉冲计数时,典型流程如下:

  1. 配置定时器基础工作参数:HAL_TIM_IC_Init()

  2. 完成输入捕获 MSP 初始化:HAL_TIM_IC_MspInit()

  3. 配置定时器从模式:HAL_TIM_SlaveConfigSynchro()

  4. 使能输入捕获并启动计数器:HAL_TIM_IC_Start()

  5. 获取计数器值:__HAL_TIM_GET_COUNTER()

  6. 设置计数器值:__HAL_TIM_SET_COUNTER()

脉冲计数配置的重点是选择正确的外部时钟源、输入通道和从模式。

七、高级定时器

1. 高级定时器简介

高级定时器常见于 TIM1TIM8

主要特性:

  • 16 位递增、递减、中心对齐计数器

  • 16 位预分频器

  • 可用于触发 DAC、ADC

  • 支持更新事件、触发事件、输入捕获、输出比较中断或 DMA 请求

  • 具备 4 个独立通道

  • 支持输入捕获、输出比较、PWM、单脉冲模式

  • 支持外部信号控制定时器和定时器互连

  • 支持编码器和霍尔传感器接口

  • 支持重复计数器

  • 支持带死区时间控制的互补输出

  • 支持断路输入,用于输出安全保护

高级定时器比通用定时器更适合复杂 PWM 控制,尤其是电机驱动和功率控制场景。

2. 高级定时器框图重点

高级定时器在通用定时器基础上,重点增加了:

模块 作用
重复计数器 控制多次溢出后才产生更新事件
互补输出 输出互补 PWM 信号
死区控制 防止上下桥臂同时导通
刹车功能 异常时快速关闭或切换输出状态

八、重复计数器与指定个数 PWM

重复计数器用于控制更新事件的产生频率。

重复计数器的关键结论:

计数器每次上溢或下溢都会使重复计数器减 1,减到 0 时产生更新事件。

如果设置 RCR = N,则更新事件会在 N + 1 次溢出后产生。

如果需要输出指定个数的 PWM,可以按以下思路理解:

  1. 配置边沿对齐模式输出 PWM。

  2. 如果要输出 N 个 PWM,则把 N - 1 写入重复计数器 RCR

  3. 在更新中断中关闭计数器。

配置步骤

使用 HAL 库配置高级定时器输出指定个数 PWM 时,典型流程如下:

  1. 配置定时器基础工作参数:HAL_TIM_PWM_Init()

  2. 完成 PWM MSP 初始化:HAL_TIM_PWM_MspInit()

  3. 配置 PWM 模式、比较值等:HAL_TIM_PWM_ConfigChannel()

  4. 设置中断优先级并使能中断:HAL_NVIC_SetPriority()HAL_NVIC_EnableIRQ()

  5. 使能定时器更新中断:__HAL_TIM_ENABLE_IT()

  6. 使能输出、主输出和计数器:HAL_TIM_PWM_Start()

  7. 编写中断服务函数:TIMx_IRQHandler(),并调用 HAL_TIM_IRQHandler()

  8. 编写更新中断回调函数:HAL_TIM_PeriodElapsedCallback()

九、高级定时器输出比较模式

输出比较模式可以根据 CNTCCRx 的比较结果改变通道输出。

输出比较模式的关键结论:

PWM 波周期或频率由 ARR 决定,占空比固定 50%,相位由 CCRx 决定。

配置步骤

使用 HAL 库配置输出比较模式时,典型流程如下:

  1. 配置定时器基础工作参数:HAL_TIM_OC_Init()

  2. 完成输出比较 MSP 初始化:HAL_TIM_OC_MspInit()

  3. 配置输出比较模式:HAL_TIM_OC_ConfigChannel()

  4. 使能通道预装载:__HAL_TIM_ENABLE_OCxPRELOAD()

  5. 使能输出、主输出和计数器:HAL_TIM_OC_Start()

  6. 根据需要修改捕获/比较寄存器值:__HAL_TIM_SET_COMPARE()

十、高级定时器互补输出、死区与刹车

1. 互补输出与死区控制

互补输出常用于半桥、全桥、电机驱动等场景。由于功率器件存在开关延迟,如果上下桥臂同时导通,会造成短路风险,因此需要加入死区时间。

死区控制的作用是:在互补信号切换时人为插入一小段两个输出都无效的时间,避免上下管直通。

2. 刹车功能

刹车功能也叫断路功能,用于在异常输入出现时,将定时器输出切换到安全状态。

使能刹车功能的关键点:

  • TIMx_BDTRBKE 位置 1。

  • 刹车输入信号极性由 BKP 位设置。

  • 输出状态受 MOEOSSIOSSROISxOISxNCCxECCxNE 等位影响。

  • 无论何时,OCxOCxN 输出都不能同时处在有效电平。

发生刹车后,可能出现以下结果:

  1. MOE 位被清零,OCxOCxN 输出进入无效、空闲或复位状态。

  2. 互补输出状态由相关控制位和参考手册定义决定。

  3. BIF 位置 1,如果使能 BIE,会产生刹车中断;如果使能 TDE,会产生 DMA 请求。

  4. 如果 AOE 位置 1,在下一个更新事件 UEV 时,MOE 会被自动置 1。

3. 互补输出带死区控制配置步骤

使用 HAL 库配置互补输出和死区控制时,典型流程如下:

  1. 配置定时器基础工作参数:HAL_TIM_PWM_Init()

  2. 完成 PWM MSP 初始化:HAL_TIM_PWM_MspInit()

  3. 配置 PWM 模式、比较值等:HAL_TIM_PWM_ConfigChannel()

  4. 配置刹车功能、死区时间等:HAL_TIMEx_ConfigBreakDeadTime()

  5. 使能输出、主输出和计数器:HAL_TIM_PWM_Start()

  6. 使能互补输出、主输出和计数器:HAL_TIMEx_PWMN_Start()

十一、高级定时器 PWM 输入模式

PWM 输入模式可以用于测量外部 PWM 信号的频率、周期和占空比。

基本思路是使用两个捕获通道配合:

  • 一个通道捕获周期相关边沿。

  • 另一个通道捕获占空比相关边沿。

  • 再通过捕获值计算频率和占空比。

配置步骤

使用 HAL 库配置 PWM 输入模式时,典型流程如下:

  1. 配置定时器基础工作参数:HAL_TIM_IC_Init()

  2. 完成输入捕获 MSP 初始化:HAL_TIM_IC_MspInit()

  3. 配置 IC1/IC2 映射、捕获边沿等:HAL_TIM_IC_ConfigChannel()

  4. 配置从模式、触发源等:HAL_TIM_SlaveConfigSynchro()

  5. 设置中断优先级并使能中断:HAL_NVIC_SetPriority()HAL_NVIC_EnableIRQ()

  6. 使能捕获、更新/捕获中断和计数器:HAL_TIM_IC_Start_IT()HAL_TIM_IC_Start()

  7. 编写中断服务函数:TIMx_IRQHandler(),并调用 HAL_TIM_IRQHandler()

  8. 编写捕获回调函数:HAL_TIM_IC_CaptureCallback()

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐