蓝桥杯(嵌入式)——输入捕获实战:从原理图到LCD显示的PWM测量全解析

张开发
2026/4/21 14:40:35 15 分钟阅读

分享文章

蓝桥杯(嵌入式)——输入捕获实战:从原理图到LCD显示的PWM测量全解析
1. 硬件连接与原理图解析先来看看硬件部分怎么连接。XL555芯片是个经典信号发生器它能产生稳定的PWM波。在蓝桥杯嵌入式开发板上这个芯片的输出引脚会连接到STM32的PA15和PB4引脚。这两个引脚可不是随便选的它们对应着定时器TIM3的通道1和TIM2的通道1这是实现输入捕获的关键。原理图上会清晰地标注这些连接但我要提醒你特别注意两点一是XL555的输出电压范围要匹配STM32的IO口电平标准通常是3.3V二是信号线要尽量短避免引入干扰。我在去年参赛时就遇到过因为信号线过长导致测量值跳变的问题后来用示波器一查才发现是信号质量太差。2. STM32CubeMX工程配置2.1 基础工程设置打开STM32CubeMX第一步选对芯片型号很重要。蓝桥杯常用的STM32型号是STM32G431系列千万别选错。配置RCC时建议把高速时钟HSE和低速时钟LSE都勾选上这样系统时钟更稳定。调试接口选择SWD模式这是最常用的调试方式。2.2 定时器输入捕获配置重点来了TIM3的配置是这样的将PB4引脚配置为TIM3_CH1从模式Slave Mode选择Reset Mode触发源Trigger Source设为TI1FP1时钟源选择Internal Clock通道1配置为Input Capture Direct Mode通道2配置为Input Capture Indirect Mode预分频器Prescaler设为79自动重装载值Auto-reload设为65535通道2的边沿检测设为Falling Edge别忘了勾选中断使能TIM2的配置和TIM3类似只是引脚换成了PA15。配置完成后记得去NVIC设置中断优先级建议设为3这个优先级比较适中。2.3 时钟树配置时钟树配置是个精细活我建议直接修改图中框出的部分把系统时钟设为170MHz。这个频率在性能和功耗之间取得了很好的平衡实测下来非常稳定。3. 代码实现详解3.1 变量定义与初始化在main.c文件中建议在151行到153行之间添加以下代码// PWM相关变量 uint16_t PWM1_T_Count; // TIM3周期计数值 uint16_t PWM2_T_Count; // TIM2周期计数值 uint16_t PWM1_D_Count; // TIM3高电平计数值 uint16_t PWM2_D_Count; // TIM2高电平计数值 float PWM1_Duty; // TIM3占空比 float PWM2_Duty; // TIM2占空比初始化完成后记得启动定时器HAL_TIM_Base_Start(htim2); HAL_TIM_IC_Start_IT(htim2, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(htim2, TIM_CHANNEL_2); HAL_TIM_Base_Start(htim3); HAL_TIM_IC_Start_IT(htim3, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(htim3, TIM_CHANNEL_2);3.2 中断回调函数实现这是整个项目的核心代码稍微复杂但逻辑清晰void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if(htim-Instance TIM2) { if(htim-Channel HAL_TIM_ACTIVE_CHANNEL_1) { PWM2_T_Count HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1) 1; PWM2_Duty (float)PWM2_D_Count / PWM2_T_Count; } else if(htim-Channel HAL_TIM_ACTIVE_CHANNEL_2) { PWM2_D_Count HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2) 1; } } if(htim-Instance TIM3) { if(htim-Channel HAL_TIM_ACTIVE_CHANNEL_1) { PWM1_T_Count HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1) 1; PWM1_Duty (float)PWM1_D_Count / PWM1_T_Count; } else if(htim-Channel HAL_TIM_ACTIVE_CHANNEL_2) { PWM1_D_Count HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2) 1; } } }这个回调函数的工作原理是当捕获到上升沿时记录当前计数值捕获到下降沿时再记录一次两个值的差就是高电平时间而整个周期的时间就是两次上升沿之间的间隔。4. LCD显示与调试技巧4.1 LCD显示实现测量结果最终要显示在LCD上这段代码很关键sprintf((char *)Lcd_Disp_String, PWM1:%05dHz,%4.1f%%, (unsigned int)(1000000/PWM1_T_Count), PWM1_Duty*100); LCD_DisplayStringLine(Line8, Lcd_Disp_String); sprintf((char *)Lcd_Disp_String, PWM2:%05dHz,%4.1f%%, (unsigned int)(1000000/PWM2_T_Count), PWM2_Duty*100); LCD_DisplayStringLine(Line9, Lcd_Disp_String);这里有个小技巧1000000/PWM_T_Count这个公式是把定时器的计数转换成频率Hz。因为定时器的时钟频率是1MHz系统时钟170MHz经过分频后所以每个计数代表1微秒。4.2 常见问题排查在实际调试中你可能会遇到这些问题测量值不稳定检查信号线是否接触良好XL555的供电是否稳定频率显示为0检查定时器配置是否正确特别是从模式和触发源设置占空比显示异常确认两个通道的边沿检测设置是否正确我建议在调试时先用示波器观察XL555的输出信号确保信号本身没有问题再排查代码。如果没条件用示波器可以尝试用LED灯观察PWM信号的大致情况。

更多文章