【STM32】定时器

STM32 定时器详解笔记

📌 定时器的本质:计数器!

STM32 中的定时器本质就是 一个可编程的计数器 。它通过对时钟脉冲进行计数,从而实现精确的时间控制。


🧩 定时器的功能

定时器不仅能"计时",还可完成丰富的功能:

  • ⏱️ 精确计时/延时
  • ⏹️ 捕获脉冲宽度(输入捕获)
  • 🧮 计算 PWM 占空比
  • 📤 输出 PWM 波形(输出比较)
  • 🔁 周期性中断事件触发
  • ⚙️ 驱动 DAC、编码器接口等

🧭 定时器的分类

定时器类型 特点
高级定时器 支持互补输出、死区时间、刹车输入等,适用于电机控制(如 TIM1、TIM8)
通用定时器 功能全面,适用于大多数计时、PWM、输入捕获等功能(如 TIM2~TIM5)
基本定时器 仅用于简单计时、中断或 DAC 触发(如 TIM6、TIM7)

⏳ STM32 如何实现"计时"?

✔️ 原理描述

以一个恒定频率的输入方波为基础,每当检测到一个脉冲(如上升沿),计数器的值加 1:

  • 若方波频率为 100Hz,则 1 秒内会产生 100 个脉冲;
  • 当计数器计满 100,就表示时间过去了 1 秒。

❓ 那么这个"方波"信号从哪来?

STM32 的定时器时钟源来自系统时钟(经过配置后从 APB 总线 分发)。

  • 通用/基本定时器:挂载在 APB1
  • 高级定时器:挂载在 APB2

举例:当系统设置时钟为 72 MHz,则定时器每秒收到 72M 个脉冲。


⚠️ 寄存器限制与预分频器的作用

  • STM32 大多数定时器计数器为 16 位 ,最大值为 65535
  • 72MHz 频率下,计满一次仅需约 0.00091s
  • 想要计较长时间怎么办?

🧱 引入预分频器(Prescaler)

预分频器本质也是一个计数器,作用是对输入时钟进行分频

  • 设置为 0 表示 1 分频(不分频)
  • 设置为 1 表示 2 分频
  • 设置为 n-1 表示 n 分频

📌 预分频器的寄存器也是 16 位,最大分频可达 65536 倍!

例如:72 MHz ÷ 65536 ÷ 65536 ≈ 0.00023 Hz,计数周期最长可达 约 59.65 秒

🔁 串联计时器

多个定时器还可以通过主从机制实现更长时间的计时(如 TIM6 作为 TIM7 的时钟源)。


📤 周期性事件与中断:自动重装载寄存器(ARR)

  • 用于设置计数器的上限值
  • 当 CNT 计满并等于 ARR,触发一次 更新事件(Update Event)
  • 此时 CNT 被重置为 0,若开启中断,也将触发一次 中断服务函数

🧠 示例用途

每 1 秒发送一次数据:

  1. 设置预分频器和 ARR,使 CNT 到达 ARR 需要 1 秒;
  2. 启用中断;
  3. 在中断回调函数中发送数据。

🧩 时钟源配置(CubeMX 中的 Internal Clock

在 CubeMX 中配置定时器时,会看到 Clock Source = Internal Clock

  • 意思是使用 来自内部时钟树 的时钟作为定时器输入;
  • 和你选择的 系统主时钟源(如 HSE 通过 PLL 放大) 是有关联的;
  • 实际上,"internal"不是指定一个固定频率,而是来自你配置的时钟树的 APB 时钟。

🔧 常用 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):

  • 设置的新值,不会立即生效
  • 只有在 CNT 发生更新事件(达到 ARR)后,新值才会被写入影子寄存器并应用;
  • 保证修改参数过程中,不影响正在运行的计数周期。

📌 CubeMX 中可设置是否启用 ARR 的影子寄存器。


🔁 中断使用说明

步骤:

  1. CubeMX 勾选 定时器全局中断(Global interrupt)
  2. 使用 HAL_TIM_Base_Start_IT(&htim) 启动中断计时器
  3. 实现回调函数 HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 处理事件

✅ 总结

STM32 的定时器结构灵活强大,不仅可以用于简单的延时控制,也能完成复杂的工业控制任务。理解定时器的本质"计数器"与其时钟来源、寄存器配置,是灵活使用其各类功能的关键。


相关推荐
邹诗钰-电子信息工程3 分钟前
bmp280的压力数据采集(i2c设备驱动+设备树编写)
stm32·单片机·嵌入式硬件
Ronin-Lotus4 小时前
嵌入式硬件篇---有线串口通信问题解决
单片机·嵌入式硬件·ttl·rs232·rs485·有线串口
GalaxySinCos5 小时前
08 51单片机之串口通信
单片机·嵌入式硬件·51单片机
悠哉悠哉愿意6 小时前
【电赛学习笔记】MaxiCAM 项目实践——与单片机的串口通信
笔记·python·单片机·嵌入式硬件·学习·视觉检测
李某学编程8 小时前
Cortex-M内核SysTick定时器介绍
stm32·单片机
李永奉8 小时前
STM32-定时器的基本定时/计数功能实现配置教程(寄存器版)
c语言·开发语言·stm32·单片机·嵌入式硬件
糖糖单片机设计8 小时前
硬件开发_基于STM32单片机的电脑底座系统
stm32·单片机·嵌入式硬件·物联网·51单片机
IT项目分享11 小时前
ESP32入门实战:PC远程控制LED灯完整指南
单片机·嵌入式硬件·micropython·it项目网
Electrical_IT14 小时前
STM32-PWM输入捕获的配置
stm32·单片机
风吹花中花吹风15 小时前
原创-锐能微82xx系列电能计量芯片软件驱动开发与精度校准流程完全指南
驱动开发·单片机·嵌入式硬件·锐能微·计量芯片·精度校准·电能表校准