STM32 通用定时器输入捕获详解:测脉宽、测频率
前面学的输出比较/PWM 是定时器"往外发波形";
本章反过来------输入捕获是定时器"盯着外面进来的信号",在边沿跳变的瞬间,硬件自动把当前计数器值记下来。
有了这个能力,单片机就能测量脉冲宽度、测量信号频率,比如测红外遥控、测舵机信号、测方波频率。
1. 要捕获信号的什么特征?
输入捕获要捕获的,是信号边沿跳变发生的"时刻"------具体说就是:
- 上升沿(低→高跳变)到来的那一刻;
- 下降沿(高→低跳变)到来的那一刻。
在那个瞬间,硬件自动把当前 TIMx_CNT 计数器的值锁存到对应的捕获/比较寄存器 TIMx_CCRx 中。
类比:
CNT 是个不停走的秒表;输入捕获就是"你喊'开始'时,秒表自动定格当前读数"。
你不用盯着秒表看,边沿一跳,读数自动进 CCR。
2. 为什么需要输入捕获?
2.1 脉冲宽度测量
比如测一个方波高电平持续了多久:
- 软件做法:
while(引脚==高);开始计时,while(引脚==低);结束计时------但这期间 CPU 啥也干不了,而且中断一来计时就不准;- 硬件做法:上升沿自动记 CNT1、下降沿自动记 CNT2,CPU 在中断里算
CNT2-CNT1就是脉宽,计时全程 CPU 可以干别的。典型应用:测舵机 PWM 信号、测红外遥控 NEC 协议的高电平宽度(区分 0 和 1)。
2.2 脉冲频率测量
一个方波信号的周期 = 相邻两个上升沿的时间差。测出周期,
频率 = 1/周期:
- 连续两个上升沿自动记 CNT1、CNT2;
周期 = CNT2 - CNT1(考虑溢出次数);频率 = CK_CNT / (CNT2 - CNT1)。典型应用:测外部信号频率、测晶振频率、测转速(码盘)。
一句话:
输入捕获 = 让硬件在边沿瞬间自动"拍照"记录计数器值,CPU 事后算时间差。
3. 是什么?
3.1 一个例子
假设 CK_CNT = 1MHz(1us 一拍),现在 PB6(TIM4_CH1)接了一个方波:
- 0.5ms 时上升沿来了 → 硬件自动把 CNT=500 锁存进 CCR1,并置位中断标志;
- 1.2ms 时下降沿来了 → 硬件自动把 CNT=1200 锁存进 CCR2;
- CPU 在中断里读到:
脉宽 = 1200 - 500 = 700us。整个过程不需要 CPU 盯着引脚,边沿事件由硬件捕获。
3.2 定义
输入捕获(Input Capture):
定时器引脚检测到指定边沿(上升沿/下降沿)时,硬件自动将当前计数器 TIMx_CNT 的值锁存到捕获/比较寄存器 TIMx_CCRx,并可触发中断/DMA 的功能。
它和输出比较是同一个 CCR 寄存器的两种身份:
- 输出比较模式:软件写 CCR → 到点硬件改引脚电平(往外发);
- 输入捕获模式:引脚边沿到来 → 硬件读 CNT 写进 CCR(往里收)。
方向相反,但用的是同一个寄存器、同一个通道。
4. 理解原理:怎么办?
4.1 结构框图简化
4.1.1 梳理原始结构框图
参考手册里通用定时器框图很复杂,抓住输入捕获这一条信号链即可:
外部引脚 TIx ──► 滤波器(ICxF) ──► 边沿检测(极性选择) ──► 预分频(ICxPSC) ──► 捕获寄存器 CCRx │ ▼ 置位 CCxIF → 中断/DMA4.1.2 TIM 和 GPIO 针脚关系
引脚要配置成浮空输入(或上拉输入)------因为是"听外面信号",方向是输入。
引脚复用关系决定哪个定时器通道能接哪个脚(如 PA6=TIM3_CH1、PA7=TIM3_CH2)。
4.1.3 简化输入捕获通道
把它简化成三段:
- 滤波器 ICxF:滤掉引脚上的毛刺噪声(连续采样 N 次一致才认可边沿),不用就设 0;
- 边沿检测 + 极性:选上升沿、下降沿还是双边沿触发;
- 捕获锁存:边沿一到,CNT 值立刻搬进 CCRx,同时置 CCxIF。
4.2 输入捕获速通(配置套路)
cpp① GPIO:对应引脚配 浮空输入 ② CCMR:CCxS[1:0]=01(通道x配为输入,映射到 TIx) ③ CCER:CCxP 选上升/下降沿;CCxE 其实输入模式下不强制 ④ DIER:CCxIE=1(使能捕获中断) ⑤ NVIC:使能对应定时器中断 ⑥ 启动:CR1.CEN=1(计数器自由跑,等边沿来捕) ⑦ 中断里读 CCRx,算时间差4.3 方波周期测量原理
只开一个通道(CH1)捕上升沿:
注意溢出:
16 位计数器最大 65535,如果周期比 65535 个计数拍还长,CNT 会溢出回绕,光靠 T2-T1 就错了。
要在更新中断(溢出中断)里记录溢出次数 ovf,
真实差值 =
(ovf × 65536) + CCR - T1。4.4 脉冲宽度测量原理
高电平宽度 = 下降沿时刻 - 上升沿时刻。
两种实现:
方法一:单通道 + 极性翻转
- CH1 捕上升沿 → 记下 CCR1=T1,然后把极性改成下降沿;
- 下降沿到来 → 再次进中断,CCR1=T2,把极性改回上升沿;
- 脉宽 = T2 - T1。
方法二:双通道(更常用)
- CH1 捕上升沿(CCR1 记 T1);
- CH2 捕下降沿(CCR2 记 T2);
- 两个通道配同一个定时器的不同引脚/或内部互联;
- 脉宽 = CCR2 - CCR1。
cpp引脚 ──────────┐ ┌───────── │ │ 上升沿 T1 ──┘──────────────┘ ──下降沿 T2 │←── 高电平 = T2 - T1 ──→│4.5 输入捕获双通道
一个通道的信号源从哪来?CCMR 的 CCxS 位决定映射关系,有三种模式:
4.5.1 直接输入模式
- TI1(引脚 1)→ 进 IC1(通道 1 的捕获单元);
- TI2(引脚 2)→ 进 IC2(通道 2 的捕获单元);
- 一一对应,最直观。
4.5.2 间接输入模式(交叉)
- TI1 → 进 IC2(交叉映射);
- TI2 → 进 IC1;
- 用于特殊同步需求。
4.5.3 直接间接输入模式(测脉宽的经典做法)
- TI1 同时进 IC1 和 IC2;
- IC1(CH1)捕上升沿、IC2(CH2)捕下降沿;
- 两个捕获单元用同一个引脚 TI1,但极性不同;
- 这样一个引脚就能同时捕获上升沿和下降沿,脉宽 = CCR2 - CCR1,不需要软件翻转极性。
这就是"直接 + 间接"配合:
TI1 直接进 IC1,又"间接"进 IC2(CC2S=11 或交叉配置),一个引脚喂两个捕获单元。
5. 整合
5.1 输入捕获中断与 DMA
- 捕获事件发生时(CCxIF 置位):
- 中断路径:在 CCx 中断服务函数里读 CCRx、算时间差(简单、常用);
- DMA 路径:把 CCRx 值自动搬到内存数组(连续采样、高频信号不丢数据,比如测一串脉冲的频率变化)。
5.2 输出比较 PWM 和输入捕获(对比)
对比项 输出比较/PWM 输入捕获 方向 定时器 → 引脚(输出) 引脚 → 定时器(输入) CCR 谁写 软件写(Pulse 占空比) 硬件写(捕获时刻的 CNT) 触发 CNT==CCR 时改引脚电平 引脚边沿到来时锁存 CNT GPIO 模式 复用推挽输出 浮空/上拉输入 用途 PWM、发波形 测脉宽、测频率 中断 更新中断/比较中断 捕获中断 CCxIF 5.3 捕获/比较模式寄存器 TIMx_CCMR1(重点寄存器)
位 名称 作用 位 1:0 CC1S1:0 通道 1 方向。 00=输出; 01=输入,IC1 映射到 TI1(直接); 10=输入,IC1 映射到 TI2(间接); 11=输入,IC1 映射到 TRC 位 3:2 IC1PSC1:0 输入捕获预分频(每 N 个边沿捕一次,一般 0=每边沿都捕) 位 7:4 IC1F3:0 输入滤波(采样次数+时钟分频,滤毛刺;初学设 0000) 配套位:
- CCER 的 CC1P:选极性(0=上升沿触发捕获,1=下降沿;CC1NP 高级定时器双边沿);
- DIER 的 CC1IE:捕获中断使能;
- SR 的 CC1IF:捕获中断标志(硬件置位、软件清零)。
6. 边沿检测器输出的猜测实现-理解
面试题
一、概念题
Q1. 什么是输入捕获?它和输出比较有什么区别?
A:
输入捕获是引脚检测到指定边沿时,硬件自动把当前 CNT 计数器值锁存到 CCRx 并置中断标志的功能,方向是"引脚→定时器"(往里收)。
输出比较是软件写 CCR、CNT==CCR 时硬件改引脚电平,方向是"定时器→引脚"(往外发)。
两者共用同一个 CCR 寄存器,靠 CCMR 的 CCxS 位切换方向。
Q2. 为什么要用硬件输入捕获,而不是软件读引脚测脉宽?
A:
软件轮询
while(引脚)测脉宽时,CPU 全程阻塞且计时不准(中断一来就打断);硬件捕获在边沿瞬间自动记 CNT,计时全程 CPU 可干别的,时间分辨率等于计数周期(us 级),精度高。
Q3. 输入捕获能测什么?
A:
两类:
① 脉冲宽度(上升沿到下降沿的时间,如舵机信号、红外遥控);
② 信号频率/周期(相邻两个同边沿的时间差取倒数)。
二、原理与配置题
Q4. 输入捕获信号链由哪几部分组成?
A:
外部引脚 TIx → 输入滤波器 ICxF(滤毛刺)→ 边沿检测(CCxP 选上升/下降沿)→ 捕获预分频 ICxPSC → 边沿瞬间把 CNT 锁存进 CCRx → 置 CCxIF,可触发中断/DMA。
Q5. 输入捕获的配置"三件套"是什么?
A:
CCMR 的 CC1S=01(通道配为输入,IC1 映射到 TI1 直接输入)+ CCER 的 CC1P=0(上升沿触发)+ DIER 的 CC1IE=1(使能捕获中断)。
另外 GPIO 配浮空/上拉输入,CR1.CEN=1 启动计数。
Q6. CCMR 里 CC1S、IC1PSC、IC1F 分别是什么?
A:
CC1S1:0:通道方向/映射,00=输出、01=输入直接映射 TI1、10=输入间接映射 TI2;
IC1PSC:捕获预分频(每 N 个边沿捕一次,一般 0=每边沿都捕);
IC1F3:0:输入滤波(连续采样多次确认边沿,滤噪声毛刺,初学设 0)。
三、测量原理题
Q7. 怎么用输入捕获测方波周期?
A:
**CH1 捕上升沿,连续两次上升沿分别记下 CCR1=T1、T2,**周期 = T2 - T1(计数拍),频率 = CK_CNT/(T2-T1)。
注意处理 CNT 溢出(16 位最大 65535),长周期要在更新中断里累计溢出次数。
Q8. 怎么测高电平脉宽?两种方法各是什么?
A:
脉宽 = 下降沿时刻 - 上升沿时刻。
方法一 单通道:
捕上升沿记 CCR,然后翻转极性捕下降沿,软件改 CC1P;
方法二 双通道:
CH1 捕上升沿(CCR1=T1)、CH2 捕下降沿(CCR2=T2),脉宽 = CCR2 - CCR1。双通道无需软件翻转极性,更常用。
Q9. 直接输入、间接输入、直接间接输入三种模式是什么?
A:
直接:TI1→IC1、TI2→IC2 一一对应;
间接(交叉):TI1→IC2、TI2→IC1;
直接间接:同一个 TI1 同时进 IC1 和 IC2,两个捕获单元极性不同(一捕上升沿、一捕下降沿),这样一个引脚就能测脉宽,是双通道测脉宽的经典接法。
Q10. 测量长信号时为什么要处理 CNT 溢出?怎么处理?
A:
CNT 是 16 位,最大 65535,一个周期超过 65535 个计数拍就会溢出回绕,光靠 CCR 相减会少算好几圈。
解决:
在更新中断(溢出中断)里累加溢出次数 ovf,
真实时间差 =
(ovf × 65536) + 当前CCR - 起始CCR。四、整合对比题
Q11. 输入捕获的中断和 DMA 怎么选?
A:
只测几个值、低频信号 → 中断(CCxIE=1,进 CCx 中断读 CCR 计算);
连续采样一串脉冲、高频不丢数据 → DMA(CCxDE=1,硬件自动把 CCR 值搬到内存数组)。
Q12. 对比输出比较/PWM 和输入捕获。
A:
输出比较/PWM 输入捕获 方向 定时器→引脚 引脚→定时器 CCR 谁写 软件写(占空比) 硬件写(捕获时刻) GPIO 复用推挽输出 浮空/上拉输入 用途 PWM、发波形 测脉宽、测频率
Q13. CK_CNT=1MHz,两次上升沿 CCR 分别是 1000 和 50000(无溢出),周期和频率是多少?
A:
周期 = 50000-1000 = 49000 拍,1MHz 下一拍 1us → 周期 49ms,
频率 = 1/0.049 ≈ 20.4 Hz。
【STM32】 通用定时器:输入捕获与输出比较详解 测脉宽、测频率
Brilliantwxx2026-10-14 18:19
相关推荐
意法半导体STM321 小时前
【官方原创】LAT1703 STM32C5 LL Cordic例程FPGA小徐2 小时前
电子工程师面试真题:LM7805 扩流 + 过流保护电路原理分析霖霖7142 小时前
【ESP32笔记】RGB灯WS2812实验西城微科方案开发2 小时前
激光测距仪模组选择——M01还是M03?zjxtxdy2 小时前
STM32hal库开发-中断与串口和通信协议霖霖7142 小时前
【ESP32笔记】开发环境的搭建wuyk5552 小时前
27.LeetCode 2265. 统计值等于子树平均值的节点数 —— 后序遍历实战糖糖单片机设计3 小时前
基于 STM32 的配网变压器涌流抑制器设计与实现威嵌神州3 小时前
10.1 寸带扩展坞维保加固平板|分体式维保终端硬件基线选型评估










