🎯 Timer_输入捕获模块 —— 给你的开发板装上“电子秒表”!
✅ 适用对象:嵌入式初学者、蓝桥杯参赛选手、传感器信号测量开发者
💡 核心目标:学会用 STM32 精准测量外部信号的频率、周期、脉宽
🧠 特色:用“拍照计时员”比喻输入捕获,用“555 小喇叭”解释信号源,小白秒懂!
🔍 一、输入捕获是什么?
输入捕获(Input Capture)是 STM32 定时器的一项高级功能:
当外部信号发生边沿跳变(上升沿或下降沿)时,定时器会自动“拍照”——把当前计数值存进寄存器,并可触发中断或 DMA。
🌟生活比喻:
想象你在跑道边当计时员:
- 运动员起跑(上升沿)→ 你按下秒表开始计时(第一次捕获)
- 运动员冲线(下一个上升沿)→ 你再次按下秒表(第二次捕获)
- 两次时间差 = 一圈用时 → 可算出速度(频率)!
✅典型用途:
- 测量 PWM 信号频率/占空比
- 解码红外遥控信号(如 NEC 协议)
- 读取编码器脉冲
- 蓝桥杯竞赛中配合XL555信号源测频
📦 二、信号源小明星:XL555 芯片
XL555是国产版NE555,不到 1 块钱的经典定时器 IC!
🛠️ 功能特点
- 可工作在单稳态(一次触发输出固定脉宽)或无稳态(自激振荡,输出方波)
- 常用于生成PWM 信号、方波、延时脉冲
- 在蓝桥杯竞赛中,常作为标准信号源,输出固定频率方波给 STM32 测量
📺 推荐视频:
【不到1块钱的小玩意,可设计出上万种电子产品!】
https://ww w.bilibili.com/video/BV1fr4y1r7Tk/?share_source=copy_web&vd_source=6b05aba58b3 63b9a543633dd8d43ce1d
⚙️ 三、CubeMX 配置详解(13 步搞定输入捕获)
1.选择定时器(Timer)
- 要求:必须支持输入捕获(通用/高级定时器均可,如 TIM1~TIM5)
- 建议:TIM2/TIM3 最常用,通道多、功能全
2.选择通道(Channel)
- 每个定时器有多个通道(CH1~CH4)
- 例如:TIM3_CH1 → 对应引脚 PA6
- 在 Pinout 图中,该引脚会自动标为TIMx_CHy
3.时钟源(Clock Source)
- 通常为APB1(低速总线)或 APB2(高速总线)
- 时钟频率决定测量精度(越高越准)
4.Prescaler(预分频器)
- 作用:降低计数频率,扩展可测信号范围
- 公式:
- 示例:72MHz ÷ (71 + 1) =1MHz(即每 1μs 计 1 次)
⚠️ 注意:Prescaler 值越大,分辨率越低,但能测更慢的信号!
5.Counter Mode(计数模式)
- 推荐:Up(向上计数)
- 从 0 → ARR,逻辑清晰,适合测频
- Center-aligned 一般用于电机控制,不用于输入捕获
6.捕获极性(Input Capture Polarity)
| 选项 | 作用 | 应用场景 |
|---|---|---|
| Rising Edge | 上升沿触发 | 测周期(相邻上升沿) |
| Falling Edge | 下降沿触发 | 特殊协议 |
| Both Edges | 双边沿触发 | 测脉宽(上升+下降) |
✅测频率→ 选Rising Edge
✅测高电平时间(脉宽)→ 先捕获上升沿,再捕获下降沿
7.捕获选择(Input Capture Selection)
- Direct TI:直接从本通道引脚捕获(99% 场景用这个!)
- Indirect / TRC:用于定时器同步(高级用法,初学者忽略)
8.滤波器(Input Capture Filter)
- 作用:抗干扰!防止毛刺误触发
- 原理:对输入信号连续采样 N 次,只有稳定才认为有效
- 设置值(0~15):
- 0 = 无滤波(最快响应)
- 3~7 = 一般噪声环境(推荐)
10 = 强干扰环境(牺牲响应速度换稳定性)
9.捕获预分频(IC Prescaler)
- 不是定时器主时钟分频!而是“每 N 个边沿才捕获一次”
- 选项:DIV1(每次边沿都捕获)、DIV2、DIV4、DIV8
- 用途:高频信号下减少中断次数(如 1MHz 信号只测每第 4 个边沿)
10.触发输入(Trigger Input)
- 用于定时器“主从模式”同步(如一个定时器触发另一个)
- 初学者可忽略,保持默认
11.中断 & DMA 设置
- 中断:每次捕获后进入 ISR 处理(适合低频信号)
- DMA:自动搬运捕获值到数组(适合高频/连续采集,推荐!)
12.ARR(自动重载值)
- 决定定时器最大计数值(如 ARR=65535 → 16 位计数)
- 影响:最大可测无溢出时间 = (ARR+1) / f_counter
- 建议:设为最大值(如 0xFFFF),避免频繁溢出中断
13.捕获中断使能
- 在 NVIC 中勾选TIMx Capture Compare Interrupt
- 或直接启用 DMA,无需中断
📐 四、关键公式大全(测频/测脉宽)
假设:
- 定时器时钟频率 = fclk
- Prescaler = P
- 计数频率 = fcnt=P+1fclk
- 两次捕获值 = C1, C2
1.信号周期(T)
2.信号频率(f)
3.高电平脉宽(Pulse Width)
- 捕获上升沿值 Crise
- 捕获下降沿值 Cfall
4.占空比(Duty Cycle)
📊 五、实战计算示例
条件:
- APB 时钟 = 72 MHz
- Prescaler = 71 → fcnt=1MHz(1μs/计数)
- 捕获值1 = 1000,捕获值2 = 2000
计算:
- 时间差 = 2000 - 1000 =1000 计数
- 周期 T = 1000 × 1μs =1ms
- 频率 f = 1 / 0.001 =1000 Hz(1kHz)✅
💻 六、底层代码与 HAL 库使用
1. 启动输入捕获(DMA 方式,高效!)
// 定义缓冲区(存放64次捕获值) uint32_t tim_ic_buffer[64]; // 启动 DMA 捕获(TIM3_CH1) HAL_TIM_IC_Start_DMA(&htim3, TIM_CHANNEL_1, tim_ic_buffer, 64);2. 数据处理函数(来自你提供的代码,已修复语法错误)
/** * @brief 处理输入捕获数据 * 计算缓冲区中捕获值的平均时间差,转换为频率(Hz) */ void ic_proc(void) { uint32_t tim_ic_temp = 0; // 对64个捕获值求和(实际应为相邻差值,此处简化) for (int i = 0; i < 64; i++) { tim_ic_temp += tim_ic_buffer[i]; } // 计算平均值(注意:实际应计算相邻差值的平均!) tim_ic_temp /= 64; // 假设定时器计数频率为 1MHz(1计数 = 1μs) // 频率 = 1 / (平均时间差) = 1e6 / tim_ic_temp tim_ic_val = (int)(1000000.0f / (float)tim_ic_temp); // 限制频率范围:1Hz ~ 20kHz if (tim_ic_val < 1) tim_ic_val = 1; if (tim_ic_val > 20000) tim_ic_val = 20000; }⚠️重要修正:
上述代码假设tim_ic_buffer存的是时间差,但 DMA 直接存的是绝对计数值!
正确做法:在 DMA 传输完成后,遍历数组计算buffer[i+1] - buffer[i]得到每个周期!
3. 中断方式(适合低频)
// 启动中断捕获 HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1); // 中断回调 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { uint32_t capture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); // 处理 capture 值(需记录上一次值以计算差值) } }🧠 本章口诀(背下来!)
🎯输入捕获像秒表,边沿一跳就拍照!
📏两次计数求差值,频率周期全知道!
🛡️滤波抗扰保准确,预分频扩测量!
📡555 发波 STM32 测,蓝桥杯里稳拿分!
💾DMA 搬运最高效,中断适合低频号!
这份笔记完整覆盖了输入捕获的所有内容,包括:
- 输入捕获硬件原理
- XL555 芯片介绍与应用场景
- CubeMX 13 项配置详解(含滤波、预分频、极性等)
- 频率/周期/脉宽计算公式 + 实战示例
- HAL 库 API 使用(DMA + 中断)
- 底层代码分析与修正建议
现在,你的开发板不仅能“打节奏”,还能精准测量外部世界的脉搏——无论是 555 的心跳、编码器的旋转,还是红外遥控的密语,统统逃不过它的“电子秒表”!⏱️✨