news 2026/6/6 2:43:41

【0605】定时器测量 PWM 的底层原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【0605】定时器测量 PWM 的底层原理

一、定时器里有几个关键寄存器

┌─────────────────────────────────────────┐ │ TIM8 定时器 │ │ │ │ CNT ← 计数器:一直在跑,每 tick +1 │ │ ARR ← 自动重装值:CNT 到这里就归零 │ │ PSC ← 预分频器:决定 CNT 跑多快 │ │ │ │ CCR1 ← 捕获/比较寄存器 1 │ │ CCR2 ← 捕获/比较寄存器 2 │ │ CCR3 ← 捕获/比较寄存器 3 │ │ CCR4 ← 捕获/比较寄存器 4 │ │ │ └─────────────────────────────────────────┘

CCR 不是用来计数的。计数的是 CNT。CCR 是一个锁存容器,用来在特定时刻"拍照"存下 CNT 的值。


二、CNT 和 CCR 的关系

你可以这样理解:

寄存器

类比

作用

CNT

秒表的指针

一直在走,从 0 数到 65535 再归零,循环往复

CCR

照相机

在信号边沿到来的瞬间,拍一张照片,把此刻 CNT 的值"冻"住存下来

ARR

秒表的刻度上限

CNT 数到这里就归零重新开始

所以 CCR 存的不是时间本身,而是边沿发生那一刻 CNT 的计数值


三、我原本的理解

"定时器根据指定的周期测量通道的电平"

这个描述更像是定时采样/轮询——每隔一段时间去看一下引脚是高还是低。这跟输入捕获完全不同。

定时采样

定时器每隔 1ms 中断 → 中断里读 GPIO 电平 → 记录高/低

问题:精度取决于采样频率,而且根本不知道边沿精确发生在哪个时刻

输入捕获(实际的方式)

信号边沿自动触发 → 硬件瞬间把 CNT 值锁存到 CCR → 通知 CPU

CPU 完全不需要轮询。是硬件在信号变化的那一瞬间自动完成的,零延迟,精度到 1 个时钟 tick。


四、输入捕获测 PWM 的完整原理

步骤图解

假设 50Hz PWM 信号(周期 20ms,高电平 1500μs):

信号: ┌──────────┐ ┌──────────┐ │ 高电平 │ 低电平 │ 高电平 │ ─────┘ 1500μs └──────────────────────────────┘ └──── ↑ ↑ 上升沿 下降沿

CNT 在后台一直从 0 往上数:0, 1, 2, 3, ... 65535, 0, 1, 2, ...

① 上升沿到来时

信号: ────────┐ │ ↑ 上升沿!硬件自动把此刻的 CNT 值存到 CCR 此时 CNT = 8000 → CCR = 8000(拍了第一张照片)

② 下降沿到来时

信号: │ │ └──────── 下降沿!硬件又自动存 CNT 到 CCR 此时 CNT = 9500 → CCR = 9500(拍了第二张照片)

③ 软件做减法

脉宽 = 第二次 CCR - 第一次 CCR = 9500 - 8000 = 1500 因为 CNT 是 1MHz(1μs/tick),所以 1500 就是 1500μs ✅

五、对应代码

在 rc_ch_isr 里:

// 上升沿来了:把"第一张照片"存起来 rc->rising_time = capture; // capture 就是此刻 CCR 的值(= CNT 的快照) rc->rising_valid = 1; // 切换为等下降沿 TIM_SET_CAPTUREPOLARITY(htim, channel, TIM_ICPOLARITY_FALLING); // ... // 下降沿来了:拿到"第二张照片",做减法 delta = capture - rc->rising_time; // 两张快照的差 = 高电平持续的 tick 数 = 微秒数

这里的capture参数来自中断入口:

cap = HAL_TIM_ReadCapturedValue(&g_tim8_handle, TIM_CHANNEL_1); // ↑ 这个函数就是读 CCR1 寄存器的值

所以整个流程是:

信号边沿 → 硬件自动 CCR = CNT → 触发中断 → 软件读 CCR → 做减法算脉宽

六、"捕获"这个词到底什么意思?

捕获 = 捕获(Capture)CNT 的值。

不是捕获信号,不是捕获电平,而是在信号边沿的瞬间,把计数器的当前值"抓"下来存到 CCR 里

这就像你在跑步比赛中,裁判在你经过终点线的瞬间按下秒表——他不是在"测量你的速度",而是在记录你到达的那一刻的时间。两次记录做差,就能算出你的速度。


七、一张图总结

信号引脚(PC6) │ │ 边沿检测器(硬件自动工作,不需要CPU参与) │ 检测到边沿? │ │ │ ├── YES → 立刻做 CCR = CNT(拍照) │ │ │ │ │ └── 触发中断通知CPU来取照片 │ │ │ └── NO → 什么都不做 │ CPU 收到中断 → 读 CCR → 做减法 → 得到脉宽(微秒)

核心要点:边沿检测和锁存 CCR 都是硬件自动完成的,CPU 只在中断里读结果做减法,所以精度极高、CPU 占用极低。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 2:43:07

快速原型对比:用快马一键生成trae solo与ide的轻量级demo

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 请使用快马平台生成一个简单的web应用,用于对比trae solo和ide在开发同一个功能时的差异。应用需要包含两个并排的代码编辑器区域,左侧模拟trae solo的轻量…

作者头像 李华
网站建设 2026/6/6 2:41:48

SPSS交叉表实战:5分钟搞定疾病相对危险度计算(附数据准备要点)

SPSS交叉表实战:5分钟掌握疾病相对危险度计算全流程在医学研究和公共卫生领域,相对危险度(Relative Risk, RR)是评估暴露因素与疾病关联强度的核心指标。想象一下,你刚收集完200名患者的病毒检测和癌症诊断数据&#x…

作者头像 李华
网站建设 2026/6/6 2:36:21

HSTracker:macOS平台终极炉石传说卡组跟踪与数据驱动决策系统

HSTracker:macOS平台终极炉石传说卡组跟踪与数据驱动决策系统 【免费下载链接】HSTracker A deck tracker and deck manager for Hearthstone on macOS 项目地址: https://gitcode.com/gh_mirrors/hs/HSTracker HSTracker是macOS平台上专业的炉石传说卡组跟踪…

作者头像 李华
网站建设 2026/6/6 2:36:00

vue-esign:构建企业级电子签名解决方案的技术实践

vue-esign:构建企业级电子签名解决方案的技术实践 【免费下载链接】vue-esign canvas手写签字 电子签名 A canvas signature component of vue. 项目地址: https://gitcode.com/gh_mirrors/vu/vue-esign 在数字化办公日益普及的今天,电子签名已成…

作者头像 李华
网站建设 2026/6/6 2:34:53

利用快马平台AI快速生成嘉立创6层板温控系统原型代码

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 请生成一个基于嘉立创6层板设计的智能温控系统原型代码。系统需要包含以下核心功能:使用STM32微控制器作为主控,通过6层板实现电源层、地层和信号层的合理分…

作者头像 李华
网站建设 2026/6/6 2:33:05

5分钟掌握PDFViewer:打造专业级Web文档浏览体验

5分钟掌握PDFViewer:打造专业级Web文档浏览体验 【免费下载链接】PDFViewer A general-purpose, web standards-based platform for parsing and rendering PDFs. 项目地址: https://gitcode.com/gh_mirrors/pdfvi/PDFViewer 在当今数字化办公环境中&#xf…

作者头像 李华