1. 输入捕获功能基础解析STM32的输入捕获功能就像给单片机装了个秒表。想象一下当你在田径场测量运动员跑完100米的时间你会按下秒表的开始和停止按钮。输入捕获的工作原理与此类似只不过它自动记录的是电信号边沿变化的时间点。在STM32G431RBT6这款芯片上输入捕获功能主要由定时器模块实现。具体来说高级定时器TIM1/TIM8和通用定时器TIM2-TIM4、TIM15-TIM17都支持这个功能。我实测下来TIM3的输入捕获性能最稳定特别适合蓝桥杯竞赛这种对精度要求较高的场景。输入捕获的核心部件是三个寄存器CNT计数器、CCR捕获/比较寄存器和ARR自动重装载寄存器。当配置为输入捕获模式时一旦检测到指定边沿上升沿或下降沿当前CNT的值就会立即被锁存到CCR中。这个机制就像拍照一样把信号变化的瞬间定格下来。2. CubeMX配置实战详解打开CubeMX时我建议先做三件事1) 在Pinout视图里确认芯片型号正确2) 在Clock Configuration里配置好系统时钟3) 在Project Manager里设置好工程路径。这些基础工作没做好后面容易出各种奇怪的问题。具体到输入捕获的配置以TIM3为例在Timers→TIM3下开启Clock Source为Internal Clock在Channel1选择Input Capture direct mode在Parameter Settings中设置Prescaler设为79假设系统时钟80MHz分频后得到1MHz计数频率Counter Mode设为UpAutoReload设为6553516位定时器的最大值在NVIC Settings中使能TIM3全局中断这里有个坑我踩过GPIO的Alternate function一定要选对。以PB4为例它的TIM3_CH1对应AF2如果选成AF1就完全没反应。建议打开芯片数据手册的Alternate function mapping表格仔细核对。3. 双通道测量频率和占空比单独测量频率其实很简单但要想同时获取占空比就需要用到双通道组合模式。这里我分享一个实测可用的方案配置TIM3的Channel1为上升沿捕获Channel2为下降沿捕获开启从模式复位功能Slave Mode→Trigger Source→TI1FP1设置触发极性为上升沿触发Trigger Polarity→Rising Edge关键代码实现// 初始化代码 HAL_TIM_IC_Start_IT(htim3, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(htim3, TIM_CHANNEL_2); __HAL_TIM_ENABLE(htim3); // 中断回调函数 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if(htim-Channel HAL_TIM_ACTIVE_CHANNEL_1){ // 上升沿捕获记录周期 period HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); } else if(htim-Channel HAL_TIM_ACTIVE_CHANNEL_2){ // 下降沿捕获记录高电平时间 pulse HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); } }计算频率和占空比的公式frequency 1000000.0f / (period 1); // 单位Hz duty_cycle (pulse 1) * 100.0f / (period 1); // 单位%4. LCD显示与调试技巧在蓝桥杯竞赛中LCD显示是必考项。我总结出几个优化显示效果的技巧使用sprintf格式化输出时建议预先定义好固定长度的字符数组char display_buf[4][20]; // 4行显示每行20字符 sprintf(display_buf[0], Freq:%7.2fHz, frequency); sprintf(display_buf[1], Duty:%6.2f%%, duty_cycle);避免频繁刷新整个屏幕只更新变化的部分。可以设置一个标志位当数据变化超过一定阈值时才刷新显示。对于跳动较大的数值可以添加简单的滤波算法#define FILTER_COEF 0.2f // 滤波系数 filtered_freq filtered_freq * (1-FILTER_COEF) new_freq * FILTER_COEF;调试时最容易遇到的问题是捕获不到信号。我的排查步骤是先用示波器确认PWM信号确实输出正常检查GPIO配置是否正确输入模式、上拉/下拉确认定时器时钟已使能__HAL_RCC_TIM3_CLK_ENABLE()检查中断优先级配置是否合理5. 竞赛实战经验分享在蓝桥杯嵌入式赛场上时间就是分数。我建议按这个流程操作硬件连接阶段使用彩色杜邦线区分信号线红色-VCC黑色-GND黄色-PWM给所有飞线贴上标签纸注明功能准备备用杜邦线防止现场线材损坏软件调试阶段先验证基础定时器功能比如1秒LED闪烁再测试PWM输出是否正常最后调试输入捕获功能性能优化技巧将频繁调用的函数放在RAM中执行使用__attribute__((section(.RAMCode))))关键中断服务函数尽量简短启用编译优化-O2级别有个特别实用的调试方法利用板载LED作为状态指示灯。比如// 在输入捕获中断中翻转LED void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); // ...其他处理代码 }这样通过观察LED的闪烁频率就能直观判断中断是否正常触发。这个方法在赛场没有示波器的情况下特别管用。
蓝桥杯嵌入式实战:STM32G431RBT6输入捕获与PWM测量全解析
1. 输入捕获功能基础解析STM32的输入捕获功能就像给单片机装了个秒表。想象一下当你在田径场测量运动员跑完100米的时间你会按下秒表的开始和停止按钮。输入捕获的工作原理与此类似只不过它自动记录的是电信号边沿变化的时间点。在STM32G431RBT6这款芯片上输入捕获功能主要由定时器模块实现。具体来说高级定时器TIM1/TIM8和通用定时器TIM2-TIM4、TIM15-TIM17都支持这个功能。我实测下来TIM3的输入捕获性能最稳定特别适合蓝桥杯竞赛这种对精度要求较高的场景。输入捕获的核心部件是三个寄存器CNT计数器、CCR捕获/比较寄存器和ARR自动重装载寄存器。当配置为输入捕获模式时一旦检测到指定边沿上升沿或下降沿当前CNT的值就会立即被锁存到CCR中。这个机制就像拍照一样把信号变化的瞬间定格下来。2. CubeMX配置实战详解打开CubeMX时我建议先做三件事1) 在Pinout视图里确认芯片型号正确2) 在Clock Configuration里配置好系统时钟3) 在Project Manager里设置好工程路径。这些基础工作没做好后面容易出各种奇怪的问题。具体到输入捕获的配置以TIM3为例在Timers→TIM3下开启Clock Source为Internal Clock在Channel1选择Input Capture direct mode在Parameter Settings中设置Prescaler设为79假设系统时钟80MHz分频后得到1MHz计数频率Counter Mode设为UpAutoReload设为6553516位定时器的最大值在NVIC Settings中使能TIM3全局中断这里有个坑我踩过GPIO的Alternate function一定要选对。以PB4为例它的TIM3_CH1对应AF2如果选成AF1就完全没反应。建议打开芯片数据手册的Alternate function mapping表格仔细核对。3. 双通道测量频率和占空比单独测量频率其实很简单但要想同时获取占空比就需要用到双通道组合模式。这里我分享一个实测可用的方案配置TIM3的Channel1为上升沿捕获Channel2为下降沿捕获开启从模式复位功能Slave Mode→Trigger Source→TI1FP1设置触发极性为上升沿触发Trigger Polarity→Rising Edge关键代码实现// 初始化代码 HAL_TIM_IC_Start_IT(htim3, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(htim3, TIM_CHANNEL_2); __HAL_TIM_ENABLE(htim3); // 中断回调函数 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if(htim-Channel HAL_TIM_ACTIVE_CHANNEL_1){ // 上升沿捕获记录周期 period HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); } else if(htim-Channel HAL_TIM_ACTIVE_CHANNEL_2){ // 下降沿捕获记录高电平时间 pulse HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); } }计算频率和占空比的公式frequency 1000000.0f / (period 1); // 单位Hz duty_cycle (pulse 1) * 100.0f / (period 1); // 单位%4. LCD显示与调试技巧在蓝桥杯竞赛中LCD显示是必考项。我总结出几个优化显示效果的技巧使用sprintf格式化输出时建议预先定义好固定长度的字符数组char display_buf[4][20]; // 4行显示每行20字符 sprintf(display_buf[0], Freq:%7.2fHz, frequency); sprintf(display_buf[1], Duty:%6.2f%%, duty_cycle);避免频繁刷新整个屏幕只更新变化的部分。可以设置一个标志位当数据变化超过一定阈值时才刷新显示。对于跳动较大的数值可以添加简单的滤波算法#define FILTER_COEF 0.2f // 滤波系数 filtered_freq filtered_freq * (1-FILTER_COEF) new_freq * FILTER_COEF;调试时最容易遇到的问题是捕获不到信号。我的排查步骤是先用示波器确认PWM信号确实输出正常检查GPIO配置是否正确输入模式、上拉/下拉确认定时器时钟已使能__HAL_RCC_TIM3_CLK_ENABLE()检查中断优先级配置是否合理5. 竞赛实战经验分享在蓝桥杯嵌入式赛场上时间就是分数。我建议按这个流程操作硬件连接阶段使用彩色杜邦线区分信号线红色-VCC黑色-GND黄色-PWM给所有飞线贴上标签纸注明功能准备备用杜邦线防止现场线材损坏软件调试阶段先验证基础定时器功能比如1秒LED闪烁再测试PWM输出是否正常最后调试输入捕获功能性能优化技巧将频繁调用的函数放在RAM中执行使用__attribute__((section(.RAMCode))))关键中断服务函数尽量简短启用编译优化-O2级别有个特别实用的调试方法利用板载LED作为状态指示灯。比如// 在输入捕获中断中翻转LED void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); // ...其他处理代码 }这样通过观察LED的闪烁频率就能直观判断中断是否正常触发。这个方法在赛场没有示波器的情况下特别管用。