当前位置: 首页 > backend >正文

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


http://www.xdnf.cn/news/3534.html

相关文章:

  • React memo
  • 《操作系统真象还原》调试总结篇
  • 在pycharm profession 2020.3上安装使用xlwings
  • 【CTFer成长之路】XSS的魔力
  • 个人健康中枢的多元化AI硬件革新与精准健康路径探析
  • JVM 如何使用性能分析工具定位代码中的性能问题?
  • 博弈论思维——AI与思维模型【90】
  • Elasticsearch 常用的 API 接口
  • npm,yarn,pnpm,cnpm,nvm,npx包管理器常用命令
  • 数字智慧方案5976丨智慧农业顶层设计建设与运营方案(59页PPT)(文末有下载方式)
  • npm命令介绍(Node Package Manager)(Node包管理器)
  • 2d 追加点
  • JDK-17 保姆级安装教程(附安装包)
  • 高等数学-第七版-下册 选做记录 习题9-7
  • 边缘检测算子对比:robert canny prewitt sobel laplace
  • VM虚拟机安装CentOS7.9
  • 实战应用MCP Server-SSE方式(url)
  • Calculus on Computational Graphs: Backpropagation
  • PHP-Cookie
  • Python10天突击--编译过程通常涉及几个关键步骤
  • 贪心算法精解(Java实现):从理论到实战
  • 博客打卡-人类基因序列功能问题动态规划
  • cv::remap() 和 cv::undistortion() 的区别
  • allure测试报告的应用
  • 「Mac畅玩AIGC与多模态11」开发篇07 - 使用自定义名言插件开发智能体应用
  • L3-040 人生就像一场旅行
  • stm32基础001(串口)
  • Astral Ascent 星界战士(星座上升) [DLC 解锁] [Steam] [Windows SteamOS macOS]
  • Linux架构篇、第1章_02源码编译安装Apache HTTP Server 最新稳定版本是 2.4.62
  • Windows11 管理员用户下无权限操作的解决方法