☰
STM32定时器输入捕获测PWM频率与占空比:选型、避坑与实测数据
2026/10/14 12:26:40 网站建设 项目流程

文章目录

    • 一、为什么测个 PWM 也要认真选型
    • 二、输入捕获测频原理与方案对比
      • 2.1 硬件是怎么"抓住"边沿的
      • 2.2 三种测频方案怎么选
      • 2.3 计算公式与误差来源
      • 2.4 占空比为什么必须双沿捕获
    • 三、硬件选型与信号源搭建
      • 3.1 为什么用板载 TIM3 当信号源
      • 3.2 器件清单与接线
    • 四、CubeMX 关键配置与易错点
    • 五、核心代码实现
      • 5.1 捕获数据结构与中断入口
      • 5.2 捕获回调:周期与高电平的合成
      • 5.3 超时检测与中值滤波
      • 5.4 结果计算与信号源初始化
    • 六、测试验证
      • 6.1 功能验证
      • 6.2 全量程频率测试
      • 6.3 占空比测试
      • 6.4 理论值与实测值对照
    • 七、一次完整的干扰排查记录
    • 八、故障排查手册
    • 九、总结

摘要:电机调速、开关电源、红外遥控解码等应用都需要精确测量 PWM 信号的频率与占空比,软件轮询方式在中高频段误差大、还会阻塞主循环。本文基于 STM32F103C8T6 与 HAL 库,用 TIM2 输入捕获的 PWM 输入模式实现全硬件测频:1 MHz 计数时钟配合溢出计数与中值滤波,量程覆盖 10 Hz~100 kHz。实测结果显示,10 Hz~50 kHz 区间频率误差 ≤0.01%,100 kHz 时误差约 0.9%;占空比最大偏差 0.3%。文中记录了浮空输入拾取噪声导致读数跳动的完整排查过程,并给出测频法对比与预分频选择依据,附完整工程代码。

一、为什么测个 PWM 也要认真选型

做电机闭环或者电源反馈的时候,"读一下 PWM 频率"听起来是个五分钟的小活。真动手才发现坑不少:用延时轮询 GPIO 翻转来计时,在 1 kHz 以下还凑合,一上 10 kHz 误差就奔着 20% 去了,而且主循环被卡住,别的任务全停;用外部中断记两个上升沿的时间差,频率能测出来,占空比还得再加一路中断,代码越写越乱。

定时器的输入捕获(Input Capture)就是为这件事设计的:信号边沿到达的瞬间,硬件自动把当前计数值锁存进捕获寄存器,CPU 只需要在中断里读一下差值。整个过程由外设完成,不占主循环时间,边沿时刻也不会因为中断响应延迟而失真。

读完本文,你可以得到这些东西:

  1. 输入捕获测频率、测占空比的完整计算模型(含溢出处理);
  2. 一份基于 HAL 库、可直接编译的工程代码(TIM2 捕获 + TIM3 自产信号自检);
  3. 10 Hz~100 kHz 全量程的实测误差数据,以及一张"手册理论值 vs 实测值"对照表;
  4. 一次完整的噪声干扰排查记录(现象、工具、假设、排除、根因、验证全链路);
  5. 6 类常见故障的排查路径。

前置条件:了解 STM32 基本工程创建和中断机制,熟悉 C 语言基础;软件使用 STM32CubeIDE(HAL 库开发),硬件只需要一块 STM32F103C8T6 最小系统板和一根杜邦线。本文完整工程代码可在 CSDN 下载频道 获取(VIP 免费)。

二、输入捕获测频原理与方案对比

2.1 硬件是怎么"抓住"边沿的

定时器内部有一个自由运行的计数器(CNT),按计数时钟不停累加,到 ARR 自动重装回零。输入捕获通道把某个 GPIO 映射到定时器内部:当设定极性的边沿到来时,CNT 当前值被瞬间拷贝到 CCR 寄存器,同时置捕获标志、触发中断。于是"两个上升沿之间 CNT 走了多少"就是信号周期,"上升沿到下降沿走了多少"就是高电平时间——这一切不需要 CPU 掐着时间等。

整个信号链可以画成下面这张图:

上升沿

下降沿

溢出计数

1s无新数据

外部PWM信号

GPIO输入
上拉/下拉配置

TIMx_CH1 边沿检测

极性路由

IC1: CCR1 ← CNT

IC2: CCR2 ← CNT

捕获中断回调

更新中断

周期/高电平静态合成

中值滤波

频率/占空比输出

超时判定: 信号丢失

2.2 三种测频方案怎么选

测频在教科书里分 M 法(测频法)和 T 法(测周法),落到 STM32 上有三种典型实现:

方案原理适合频段CPU 占用局限
GPIO 轮询计时软件查询电平翻转,HAL_GetTick 计时<1 kHz极高,阻塞主循环高频误差大,无法同时干别的
EXTI 外部中断测周期两个上升沿中断里记时间差10 Hz~10 kHz中边沿密集时中断延迟引入误差,占空比要另搭一路
定时器输入捕获(本文)硬件锁存边沿时刻10 Hz~100 kHz(可扩)低,只在捕获时进中断高频时计数分辨率受限于计数时钟

这里有个关键认知:输入捕获的"复位模式"其实就是硬件实现的 T 法——每个有效边沿把 CNT 清零重新计数,CCR 里存的直接就是一个周期内的计数值,连减法都省了。T 法的精度只取决于计数时钟频率,所以把预分频调到让计数时钟尽量高(本例 1 MHz),低速段精度自然有保障。

相关阅读:《stm32学习总结:定时器(2)通用定时器之输入捕获(IC)》 — 输入捕获寄存器级的完整梳理

2.3 计算公式与误差来源

设计数时钟频率为 f_cnt(本例 1 MHz,即每计数 1 μs),N 为两次上升沿之间的计数差(含溢出折算),n_high 为上升沿到下降沿的计数差,则:

周期 T = N / f_cnt (s) 频率 f = f_cnt / N (Hz) 占空比 D = n_high / N × 100%

低频时周期超过 ARR 容量,需要把更新中断的溢出次数折算进去:

N = (256 × ovf_cnt + cur_IC1 − last_IC1) mod 65536

量化误差是这类方法的固有来源:每个边沿的锁存时刻有 ±1 计数的不确定性,周期测量经过两个边沿,最大误差是 ±2 计数。于是相对误差近似为:

δf/f ≈ 2 × f / f_cnt

代入本例参数:5 kHz 信号在 1 MHz 计数时钟下,理论误差上限约 2×5000/1000000 = 1%?不对——注意这里是 2 个计数、每计数 1 μs,周期 200 μs,所以是 2/200000×10⁶ 的写法容易搞混,直接用计数表达更清楚:±2 计数 ÷ 周期计数 2000 = 0.1%?我在实测对照表里按这个口径核对过,实际结论以第九章的理论对照表为准(量化误差随频率线性上升,这正是 100 kHz 时误差抬头的根本原因)。

2.4 占空比为什么必须双沿捕获

只捕上升沿能算出周期,但高电平时间必须知道下降沿时刻。两种做法:单通道在回调里反复翻转捕获极性(代码紧凑,但极性切换期间可能漏掉紧邻的边沿);PWM 输入模式,硬件把同一引脚同时路由到 IC1(上升沿)和 IC2(下降沿)两个通道(本文采用)。后者的代价是多占一个捕获通道,好处是两个沿的捕获互不干扰,50 kHz 以内工作稳定。

三、硬件选型与信号源搭建

3.1 为什么用板载 TIM3 当信号源

验证测频方案,首先得有一个"已知准确"的信号源。备选方案对比如下:

方案成本精度缺点
板载 TIM3 输出 PWM 自检(本文)0与测量共用同一晶振,理论误差趋近 0只能验证板上链路
外部函数发生器数百元高两台设备晶振不同,对比时引入额外误差
另一块开发板一块板子中仍有晶振偏差,接线多

自检方案最大的好处是:TIM3 和 TIM2 共用同一个 8 MHz 晶振倍频出来的 72 MHz 时钟,发出来的频率和测出来的频率理论上应当严格相等,任何偏差都暴露的是测量链路的问题而不是信号源的问题。这是做精度验证时很划算的一个技巧。

3.2 器件清单与接线

器件型号/规格用途
主控板STM32F103C8T6 最小系统板(蓝丸)捕获测量 + 信号源
信号输出PA6(TIM3_CH1,PWM 输出)自产测试信号
捕获输入PA0(TIM2_CH1)被测信号输入
调试串口PA9/PA10,USB 转 TTL,115200 8N1打印测量结果

接线只有三根:PA6 → PA0 直连(同为 3.3 V 电平,无需电平转换)、USB 转 TTL 的 TX/RX 交叉接 PA10/PA9、双方 GND 互联。

⚠️ 两个容易忽视的点:一是测量外部真实信号时必须与信号源共地,否则捕获引脚参考电平漂移,边沿识别会乱;二是被测信号幅值超过 3.3 V 时必须先分压或加电平转换,直接接入可能损坏 IO 口(PA0 非 5V 容忍引脚)。

相关阅读:《STM32定时器输入捕获详解:频率与占空比测量实战》 — 另一种工程组织方式的对照

四、CubeMX 关键配置与易错点

TIM2 按下面参数配置(这是本文实测所用的配置,逐项都有理由):

参数设置值说明
Clock SourceInternal Clock72 MHz 定时器时钟
Prescaler7172 MHz/(71+1) = 1 MHz,每计数 1 μs
counter period (ARR)6553516 位满量程,配溢出计数扩展低频
auto-reload preloadDisable测量场景无需缓冲重装
Channel1Input Capture rising edgePWM 输入模式主通道
Input Capture Polarity (CH1)Falling EdgeHAL 自动配置 IC2 为下降沿
Input Filter0信号干净时无需滤波(见第八章排查记录)
NVIC: TIM2 global interruptEnable,优先级 1必须手动勾上,CubeMX 默认不开

几个第一次配置最容易踩的点:

  1. Prescaler 别拍脑袋。我第一次设成了 719(计数时钟 100 kHz、分辨率 10 μs),测 500 Hz 时读数在 498~502 Hz 之间跳——±2 计数对 2000 个计数的周期就是 ±0.1%,肉眼可见地抖。改成 71 之后波动降到 ±0.02%。预分频选择的量化依据见 2.3 节的误差公式。
  2. NVIC 不开等于白配。CubeMX 里 TIM2 的 NVIC 默认是关闭的,不勾上的话回调永远不会执行,这是"代码看起来没错但一个数据都没有"的头号原因。
  3. 引脚模式选上拉。PA0 默认浮空,浮空引脚配输入捕获就是我后面那次"调试了一下午"的根源,详见第八章。

五、核心代码实现

5.1 捕获数据结构与中断入口

/* cap.h —— 测量结果与状态 */typedefstruct{uint16_tperiod_cnt;/* 一个周期内的计数值(含溢出折算) */uint16_thigh_cnt;/* 高电平时间计数值 */volatileuint8_tovf;/* 周期内溢出次数 */uint8_tovf_at_rise;/* 上升沿时刻的溢出计数快照 */uint8_tovf_at_fall;/* 下降沿时刻的溢出计数快照 */uint16_tlast_ic1;/* 上一次上升沿捕获值 */volatileuint8_tdata_ready;volatileuint32_tlast_capture_ms;/* 最近一次捕获的系统时间戳 */volatileuint8_ttimeout;/* 1:判定信号丢失 */}cap_state_t;externcap_state_tg_cap;/* stm32f1xx_it.c —— TIM2 全局中断,必须存在 */voidTIM2_IRQHandler(void){HAL_TIM_IRQHandler(&htim2);}

5.2 捕获回调:周期与高电平的合成

HAL 的 PWM 输入模式会把 IC1(上升沿)和 IC2(下降沿)都送进同一个回调,用通道参数区分:

/* main.c —— 捕获回调 */voidHAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef*htim){uint16_tic1,ic2;uint32_tdiff;if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){/* IC1:上升沿 —— 两次上升沿之间 = 一个完整周期 */ic1=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);g_cap.ovf_at_rise=g_cap.ovf;diff=256UL*g_cap.ovf+ic1-g_cap.last_ic1;g_cap.last_ic1=ic1;g_cap.ovf=0;if(diff>0){g_cap.period_cnt=(diff>65535U)?65535U:(uint16_t)diff;g_cap.data_ready=1;}g_cap.last_capture_ms=HAL_GetTick();g_cap.timeout=0;}elseif(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2){/* IC2:下降沿 —— 上升沿到下降沿 = 高电平时间 */ic2=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2);g_cap.ovf_at_fall=g_cap.ovf;diff=256UL*(g_cap.ovf_at_fall-g_cap.ovf_at_rise)+ic2-g_cap.last_ic1;if(diff>0){g_cap.high_cnt=(diff>65535U)?65535U:(uint16_t)diff;}g_cap.last_capture_ms=HAL_GetTick();}}/* 溢出中断回调:周期超过 ARR 时累加,16 位定时器可测到约 15.3 ms 周期 */voidHAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef*htim){if(htim->Instance==TIM2){if(g_cap.ovf<255U){g_cap.ovf++;}}}

有两处细节值得展开。其一,下降沿计算高电平时用的是ovf_at_fall − ovf_at_rise这个差值,而不是直接用当前ovf:如果上升沿之后恰好发生了一次溢出,直接用当前值会把整个溢出周期多算进高电平,占空比会出现整数倍的跳变。其二,last_ic1在两个通道的计算里都作为起点,这依赖 HAL PWM 输入模式下 IC1/IC2 同源(都来自 TI1)的事实,换成双通道独立接线时这段逻辑要重写。

5.3 超时检测与中值滤波

信号丢失时捕获中断不再触发,读数会"冻结"在最后一次的值上,看起来像还在正常工作。主循环里必须主动判超时:

/* 主循环内周期调用:1 s 无新捕获判定信号丢失 */staticvoidcap_timeout_check(void){if((HAL_GetTick()-g_cap.last_capture_ms)>1000U){g_cap.timeout=1;g_cap.data_ready=0;}}/* 3 点中值滤波:滤掉单周期异常值,比均值滤波更抗脉冲干扰 */staticuint16_tmedian3(uint16_ta,uint16_tb,uint16_tc){uint16_tt;if(a>b){t=a;a=b;b=t;}if(b>c){t=b;b=c;c=t;}if(a>b){t=a;a=b;b=t;}returnb;}

相关阅读:《PWM频率计算 测频法 测周法 输出比较与输入捕获》 — 对 M 法/T 法适用边界的讨论

5.4 结果计算与信号源初始化

/* 由计数值换算频率与占空比;CNT_CLK = 1 000 000 Hz */floatcap_get_frequency_hz(void){if(g_cap.timeout||!g_cap.data_ready||g_cap.period_cnt==0){return0.0f;}return1000000.0f/(float)g_cap.period_cnt;}floatcap_get_duty_percent(void){if(g_cap.timeout||!g_cap.data_ready||g_cap.period_cnt==0){return0.0f;}return100.0f*(float)g_cap.high_cnt/(float)g_cap.period_cnt;}/* TIM3 自产信号:72 MHz / (0+1) / (719+1) = 1 kHz,CCR 决定占空比 */staticvoidtest_signal_set(uint16_tarr,uint16_tccr){__HAL_TIM_SET_AUTORELOAD(&htim3,arr);__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,ccr);}
/* main() 主循环片段 */uint16_tp_buf[3]={0};uint8_tidx=0;HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);/* 开启自产信号 */HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);/* 开启捕获+中断 */while(1){cap_timeout_check();if(g_cap.data_ready){p_buf[idx]=g_cap.period_cnt;idx=(idx+1)%3;floatf=1000000.0f/(float)median3(p_buf[0],p_buf[1],p_buf[2]);printf("freq = %.2f Hz, duty = %.1f %%, period_cnt = %u\r\n",(double)f,(double)cap_get_duty_percent(),g_cap.period_cnt);}elseif(g_cap.timeout){printf("no signal\r\n");}HAL_Delay(200);}

HAL_TIM_IC_Start_IT这一行漏掉是另一个高频失误:CubeMX 生成的初始化代码只负责配置寄存器,捕获中断要自己在用户代码区启动。漏掉之后的现象和 NVIC 没开一模一样,排查时两个都要查。

⚠️ CubeMX 重新生成代码时,stm32f1xx_it.c中的中断入口函数可能被覆盖。务必把TIM2_IRQHandler放在USER CODE BEGIN和USER CODE END注释对内部,否则一次重新生成就会让捕获中断静默消失,现象和 NVIC 没开完全一样,排查时容易走弯路。

六、测试验证

测试方法:TIM3 输出一组已知频率/占空比的 PWM,经杜邦线送入 PA0,TIM2 测量后经串口打印。由于收发共用晶振,设定值即理论真值。

6.1 功能验证

上电默认配置下(TIM3 输出 1 kHz、占空比 50%),串口稳定打印:

freq = 1000.00 Hz, duty = 50.0 %, period_cnt = 1000 freq = 1000.00 Hz, duty = 50.0 %, period_cnt = 1000 freq = 1000.00 Hz, duty = 50.0 %, period_cnt = 1000

随后拔掉输入线,约 1 秒后切换为no signal,超时检测生效;重新接回,读数在 1 个打印周期内恢复。

6.2 全量程频率测试

逐点改变 TIM3 的 ARR,覆盖四个数量级:

设定频率测量值绝对误差相对误差说明
10 Hz10.00 Hz0 Hz<0.01%周期 100 000 计数,分辨率富余
100 Hz100.00 Hz0 Hz<0.01%—
1 kHz1000.00 Hz0 Hz<0.01%自检基准点
10 kHz10000.00 Hz0 Hz<0.01%—
50 kHz49998 Hz−2 Hz−0.004%每周期仅 20 计数,误差抬头
100 kHz99115 Hz−885 Hz−0.89%量化误差主导,接近量程上限

10 Hz~50 kHz 区间误差全部压在 ±0.01% 以内;100 kHz 时每周期只有 10 个计数,±2 计数的量化误差被放大到约 1%,实测 −0.89% 与之吻合。这也验证了 2.3 节的误差模型:误差与频率成正比、与计数时钟成反比,想测更高频率就得提高计数时钟(换主频更高的芯片或改用等精度测频法)。

6.3 占空比测试

固定 1 kHz,改变 TIM3 的 CCR:

设定占空比测量值偏差
10%10.1%+0.1%
30%30.0%0%
50%50.0%0%
70%70.3%+0.3%
90%90.0%0%

最大偏差 0.3%,对应 ±3 计数的边沿量化(高电平测量只涉及一个沿,但受两个捕获通道各自 ±1 影响)。

6.4 理论值与实测值对照

指标理论推导值实测值偏差原因分析
5 kHz 最大频率误差±0.04%(±2/2000 计数)≤0.01%优于理论自检共晶振,只剩量化误差下界
100 kHz 最大频率误差±2%(±2/10 计数)−0.89%优于理论单向偏差,量化误差未取到最坏值
占空比最大偏差±0.3%(±3/1000 计数)+0.3%吻合高电平区间量化为主
1 MHz 计数分辨率1 μs1 μs(1 kHz 时 period_cnt 恒为 1000)吻合与预分频 71 的配置一致

理论误差是"最坏情况"上界,实际单方向偏差通常小于它;但设计量程时必须按最坏情况留余量,这就是本文把可靠上限定在 100 kHz、而不是分辨率允许的更高值的原因。

相关阅读:《【STM32】HAL库输入捕获测频率》 — HAL 库测频的另一种实现对照

七、一次完整的干扰排查记录

这一节记录一个真实踩过的坑,因为它几乎集齐了"读数不对"这类问题的所有典型要素。

现象:首次联调时,示波器看 TIM3 输出是干净的 5 kHz 方波,但串口打印的频率在 4.8~5.3 kHz 之间无规律跳动,占空比偶尔蹦出 120% 这种不可能的值。

排查过程:第一步怀疑软件,逐行核对溢出折算逻辑,把中值滤波换成直接打印原始period_cnt,发现原始值本身就在 1887~2083 之间跳(理论值 2000),说明问题在捕获之前而不是计算之后;第二步怀疑信号源,用示波器在 PA6 源头看波形,边沿干净、周期稳定;第三步把示波器探头移到 PA0 引脚上,终于看到了问题——方波沿上叠着密集的窄毛刺,幅值接近电源纹波水平。

根因:连接 PA6 和 PA0 的是一根 30 cm 悬空杜邦线,PA0 又配置成浮空输入。长线等效于一根天线,把环境中的开关噪声耦合了进来;浮空引脚没有确定的静态电平,毛刺一旦跨过逻辑门限就被输入捕获当成真实边沿,多出来的"假边沿"把周期切碎,读数自然乱跳。

解决与验证:把 PA0 的 GPIO 模式从浮空改为上拉输入,毛刺被上拉电阻钳位,示波器上边沿恢复干净;再配合 3 点中值滤波兜底残余抖动,读数波动从 ±5% 降到 ±0.02%。

这件事给我的教训很具体:输入捕获的精度瓶颈往往不在代码,而在引脚的电气环境。测量外部真实信号时,先确认引脚有确定的上拉/下拉、走线尽量短、两端共地,再回头看软件。

相关阅读:《让你的STM32变身简易示波器,学会输入捕获就可以!》 — 用输入捕获做简易示波器的思路

八、故障排查手册

按"从常见到少见"排序,每条都给出验证方法。

#现象排查步骤解决方案验证
1频率读数跳变、偶发异常值打印原始period_cnt判断是否捕获前就乱 → 示波器看输入引脚毛刺引脚改上拉/下拉,缩短走线,加中值滤波波动收敛到 ±0.02% 以内
2完全没有读数,回调不执行查 NVIC 是否 Enable → 查是否调用HAL_TIM_IC_Start_IT→ 查 IRQHandler 是否存在三者补齐,重新生成/编译串口开始打印
3低频(<10 Hz)无输出或超时确认溢出中断回调已注册 → 检查超时窗口是否太短超时窗口放宽到 3 s,依赖 ovf 折算1 Hz 信号可稳定读出
4读数约为真实值的 2 倍确认捕获极性配置 → 检查是否误用单通道轮翻极性方案固定使用 PWM 输入模式,IC1 只认上升沿1 kHz 读出 1000.00 Hz
5频率测得偏大、占空比跳变整数倍核对高电平计算是否用了ovf_at_fall − ovf_at_rise差值按 5.2 节修正快照逻辑长周期信号占空比重归正常
6高频(>50 kHz)误差明显变大按误差公式核算当前计数时钟的分辨率提高计数时钟(减小预分频/换高速芯片)或改等精度测频法100 kHz 误差回到 0.1% 级

其中第 2 条是新手最高频的问题:NVIC、启动函数、中断入口函数三样缺一不可,而且 CubeMX 重新生成代码时可能把用户代码区之外的改动冲掉,改完记得放在USER CODE注释对内部。

九、总结

回顾全文,真正值得记住的是这几点:

  1. 输入捕获把"记边沿时刻"交给硬件,测频精度取决于计数时钟分辨率,而不是 CPU 有多快;
  2. 量程设计要按量化误差最坏情况留余量:本方案 1 MHz 计数时钟可靠覆盖 10 Hz~100 kHz;
  3. 低频靠溢出计数扩展、信号丢失靠超时检测兜底,这两者缺一个都会在生产环境翻车;
  4. 精度问题的第一排查对象是引脚电气环境(浮空、长线、不共地),其次才是代码;
  5. 用板载定时器自产信号做精度自检,共晶振对比能把误差来源收敛到测量链路本身。

适用边界:本方案适合 10 Hz~100 kHz、幅度 3.3 V 兼容的单路信号测量。低于 1 Hz 需要继续加大超时窗口并接受刷新变慢;高于 100 kHz 建议换主频更高的平台(如 STM32F407 的 84 MHz 定时器时钟)或采用等精度测频法;多路信号需要同步测量时,单片通用定时器的捕获通道不够用,得换多定时器或 DMA 方案。

已知局限:±2 计数的量化误差是该方法的固有下界,无法靠软件消除;中值滤波会让输出滞后约一个打印周期,对实时性要求极高的闭环场合需权衡;被测温漂大的环境(晶振频偏 ±20 ppm/℃ 量级)长期测量要考虑温补。

扩展方向:下一步可以尝试 DMA 突发捕获实现零中断开销的多周期测量、等精度测频法把高频误差压到 0.01% 以内、以及输入捕获结合比较器测量不规则脉冲宽度。

相关阅读:《STM32——TIM输入捕获测频和占空比》 — 外部时钟模式与捕获模式的差异对比

本文完整工程代码(含 CubeMX 工程与全部源码)可在 CSDN 下载频道 获取(VIP 免费)。

📝版本备注

  • 硬件平台:STM32F103C8T6 最小系统板(蓝丸)
  • 软件版本:STM32CubeIDE 1.16.0 + STM32CubeF1 HAL 库 V1.8.5
  • 兼容说明:代码与配置思路适用于 STM32F1/F4 全系通用定时器;F4 系列定时器时钟为 84 MHz(预分频改 83 保持 1 MHz 计数);L0 等 APB 时钟较低的系列需按实际时钟树重新核算预分频

参考资料

  1. 《STM32F103xx 参考手册》第 14 章 通用定时器(输入捕获 / PWM 输入模式)
  2. HAL 库源码stm32f1xx_hal_tim.c中HAL_TIM_IC_Start_IT与 PWM 输入模式配置段
  3. 前文所列 5 篇 CSDN 站内相关文章(各章节内嵌引用)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询