【STM32】 通用定时器:输入捕获与输出比较详解 测脉宽、测频率


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 → 中断/DMA
4.1.2 TIM 和 GPIO 针脚关系

引脚要配置成浮空输入(或上拉输入)------因为是"听外面信号",方向是输入。

引脚复用关系决定哪个定时器通道能接哪个脚(如 PA6=TIM3_CH1、PA7=TIM3_CH2)。

4.1.3 简化输入捕获通道

把它简化成三段:

  1. 滤波器 ICxF:滤掉引脚上的毛刺噪声(连续采样 N 次一致才认可边沿),不用就设 0;
  2. 边沿检测 + 极性:选上升沿、下降沿还是双边沿触发;
  3. 捕获锁存:边沿一到,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。


相关推荐
意法半导体STM321 小时前
【官方原创】LAT1703 STM32C5 LL Cordic例程
stm32·单片机·嵌入式硬件·stm32c5·ll cordic
FPGA小徐2 小时前
电子工程师面试真题:LM7805 扩流 + 过流保护电路原理分析
单片机·嵌入式硬件
霖霖7142 小时前
【ESP32笔记】RGB灯WS2812实验
笔记·单片机·mcu·物联网
西城微科方案开发2 小时前
激光测距仪模组选择——M01还是M03?
单片机·嵌入式硬件
zjxtxdy2 小时前
STM32hal库开发-中断与串口和通信协议
stm32·单片机·嵌入式硬件
霖霖7142 小时前
【ESP32笔记】开发环境的搭建
单片机·mcu·物联网
wuyk5552 小时前
27.LeetCode 2265. 统计值等于子树平均值的节点数 —— 后序遍历实战
stm32·单片机·嵌入式硬件·算法
糖糖单片机设计3 小时前
基于 STM32 的配网变压器涌流抑制器设计与实现
人工智能·stm32·嵌入式硬件·51单片机·语音识别
威嵌神州3 小时前
10.1 寸带扩展坞维保加固平板|分体式维保终端硬件基线选型评估
嵌入式硬件·平板