【STM32】定时器使用指南与优化建议
STM32 定时器详解笔记
📌 定时器的本质:计数器!
STM32 中的定时器本质就是 一个可编程的计数器。它通过对时钟脉冲进行计数,从而实现精确的时间控制。
🧩 定时器的功能
定时器不仅能“计时”,还可完成丰富的功能:
🧭 定时器的分类
定时器类型 | 特点 |
---|---|
高级定时器 | 支持互补输出、死区时间、刹车输入等,适用于电机控制(如 TIM1、TIM8) |
通用定时器 | 功能全面,适用于大多数计时、PWM、输入捕获等功能(如 TIM2~TIM5) |
基本定时器 | 仅用于简单计时、中断或 DAC 触发(如 TIM6、TIM7) |
⏳ STM32 如何实现“计时”?
✔️ 原理描述
以一个恒定频率的输入方波为基础,每当检测到一个脉冲(如上升沿),计数器的值加 1:
❓ 那么这个“方波”信号从哪来?
STM32 的定时器时钟源来自系统时钟(经过配置后从 APB 总线 分发)。
举例:当系统设置时钟为 72 MHz
,则定时器每秒收到 72M
个脉冲。
⚠️ 寄存器限制与预分频器的作用
0.00091s
;🧱 引入预分频器(Prescaler)
预分频器本质也是一个计数器,作用是对输入时钟进行分频:
0
表示 1 分频(不分频)1
表示 2 分频n-1
表示 n 分频📌 预分频器的寄存器也是 16 位,最大分频可达 65536
倍!
例如:
72 MHz ÷ 65536 ÷ 65536 ≈ 0.00023 Hz
,计数周期最长可达 约 59.65 秒
🔁 串联计时器
多个定时器还可以通过主从机制实现更长时间的计时(如 TIM6 作为 TIM7 的时钟源)。
📤 周期性事件与中断:自动重装载寄存器(ARR)
🧠 示例用途
每 1 秒发送一次数据:
- 设置预分频器和 ARR,使 CNT 到达 ARR 需要 1 秒;
- 启用中断;
- 在中断回调函数中发送数据。
🧩 时钟源配置(CubeMX 中的 Internal Clock
)
在 CubeMX 中配置定时器时,会看到 Clock Source = Internal Clock
:
🔧 常用 HAL 函数与宏定义
🔹 基础控制
函数 | 功能 |
---|---|
HAL_TIM_Base_Start(&htim) |
启动定时器基础功能(不启用中断) |
HAL_TIM_Base_Start_IT(&htim) |
启动定时器并启用更新中断 |
__HAL_TIM_GET_COUNTER(&htim) |
获取当前计数器值 |
HAL_TIM_SET_COUNTER(&htim, val) |
设置 CNT 的初始值 |
__HAL_TIM_GET_AUTORELOAD(&htim) |
获取自动重装载值 |
__HAL_TIM_SET_PRESCALER(&htim, val) |
设置预分频值 |
🧠 宏函数命名特点
带有 __HAL_
开头、全部大写的函数,一般为底层直接寄存器操作的宏定义。
🧱 影子寄存器机制
💡 为什么我们设置的值不会立刻生效?
定时器的 预分频器 PSC 和 自动重装载寄存器 ARR 都存在影子寄存器(Shadow Register):
📌 CubeMX 中可设置是否启用 ARR 的影子寄存器。
🔁 中断使用说明
步骤:
- CubeMX 勾选 定时器全局中断(Global interrupt)
- 使用
HAL_TIM_Base_Start_IT(&htim)
启动中断计时器 - 实现回调函数
HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
处理事件
✅ 总结
STM32 的定时器结构灵活强大,不仅可以用于简单的延时控制,也能完成复杂的工业控制任务。理解定时器的本质“计数器”与其时钟来源、寄存器配置,是灵活使用其各类功能的关键。
作者:hallo-ooo