要让输入捕获真正起作用,需三者协同:GPIO必须配置为上拉/浮空输入(如GPIO_Mode_IPU),引脚速度≥50MHz;定时器须开启APB1时钟、正确设置PSC与ARR以获得目标分辨率(如1μs需PSC=71);捕获通道须绑定TIx输入路径并启用对应中断,缺一时基或GPIO时钟均会导致TIM_GetCapture1()恒为0。

怎么配 GPIO 和定时器才能让输入捕获真正起作用
输入捕获不是“开了中断就能用”,它依赖三个硬件协同:GPIO 引脚必须正确接入信号、定时器时基必须稳定运行、捕获通道必须绑定到对应 TIx 输入路径。常见错误是 GPIO 配成推挽输出还接外部信号,或者忘了开 TIM 的 RCC 时钟,导致 TIM_GetCapture1() 始终返回 0。
实操建议:
- GPIO 模式选
GPIO_Mode_IPU(上拉输入)或GPIO_Mode_IN_FLOATING(浮空输入),避免悬空抖动;引脚速度设为GPIO_Speed_50MHz以上,确保边沿响应及时 - 定时器时基配置中,
ARR(自动重装载值)和PSC(预分频)共同决定计数频率。例如想实现 1 μs 分辨率,APB1 时钟为 72 MHz,则需设PSC = 71,ARR = 0xFFFF(65535),这样CNT每加 1 就是 1 μs - 务必调用
RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_TIM3, ENABLE)和RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA, ENABLE),缺一不可
为什么上升沿+下降沿切换是测脉宽的关键动作
单次捕获只记录一个时间点,脉宽本质是“上升沿时刻”到“下降沿时刻”的差值。STM32 的输入捕获寄存器(如 CCR1)不会自动记住前一次值,也不支持双沿同时锁存——你必须手动在第一次捕获后立刻改写极性,否则第二次来的还是上升沿,结果就是 t2 - t1 ≈ 0 或直接溢出。
实操建议:
- 在第一次捕获中断里,读取
TIM_GetCapture1(TIM3)存为t1,然后立即调用TIM_OC1PolarityConfig(TIM3, TIM_ICPolarity_Falling) - 第二次捕获中断触发时,再读
TIM_GetCapture1(TIM3)得t2,此时t2 - t1才是真实高电平持续的计数值 - 注意:若信号周期短于定时器溢出周期,可不处理溢出;若可能超长(比如测遥控 NEC 码的 9ms 引导脉冲),就得配合更新中断(
TIM_IT_Update)统计溢出次数
测频率时为什么推荐用“复位从模式”而不是纯靠两次上升沿
单纯用两次上升沿算周期,容易受定时器溢出干扰:如果第一次捕获后 CNT 溢出好几次才来第二次,你得自己累加溢出次数,代码易错且难调试。而启用从模式(SMCR 配置为 Reset 模式),能让每次上升沿到来时自动清零 CNT,这样第二次捕获值直接就是周期值,无需减法和溢出补偿。
实操建议:
- 调用
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1)指定触发源 - 再调用
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset)启用复位从模式 - 此时只要保证
TIM_ICPolarity_Rising,每次上升沿都会触发捕获 + 清零CNT,读CCR1就是半个周期?不对——是完整周期对应的计数值 - 频率计算公式就是
f_signal = f_timer / CCR1_value,其中f_timer是你配置好的计数频率(如 1 MHz)
溢出和噪声导致的误捕获怎么过滤
真实环境中,信号常带毛刺,比如霍尔传感器输出抖动,可能在 1 μs 内连续触发多次上升沿,导致 CCR1 被反复覆盖,最终读到的不是有效边沿而是噪声值。滤波不是可选项,是必须项。
实操建议:
- 硬件滤波靠
TIM_ICFilter参数:设为0x0F表示采样 8 个时钟周期内电平稳定才认定为有效边沿(具体见参考手册“ICx Filter”章节) - 软件滤波靠状态机:定义
volatile uint8_t cap_state,仅当cap_state == 0时响应上升沿并置 1,下降沿到来且cap_state == 1时才计算脉宽并清零状态 - 避免在中断里做浮点运算或串口打印——这些操作耗时远超信号周期,会丢后续边沿;把
t1、t2存入全局变量,主循环再处理计算和输出
实际项目里最常被忽略的是定时器时钟源与 APB 总线频率的关系。比如 TIM3 挂在 APB1 上,而 APB1 可能被倍频(如 HCLK/2),这时你按 72 MHz 直接算 PSC 就会错。查寄存器 RCC_CFGR 或用 RCC_GetClocksFreq() 确认真实时钟频率,比背公式重要得多。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











