基于STM32的输入捕获实验

张开发
2026/4/14 18:26:33 15 分钟阅读

分享文章

基于STM32的输入捕获实验
一、实验简介输入捕获是STM32定时器的重要功能之一可以用来**测量脉冲宽度**或**测量信号频率**。其基本原理是通过检测TIMx_CHx引脚上的边沿信号当边沿信号发生跳变上升沿或下降沿时将当前定时器计数器的值存放到对应的捕获/比较寄存器中完成一次捕获。**实验目标**学习通用定时器的输入捕获功能捕获输入信号的高电平脉宽并通过串口打印测量结果。**硬件资源**- 通用定时器TIM2_CH1PA0作为输入捕获通道- 串口1TX→PA9RX→PA10用于打印结果- 可选TIM3_CH1PA6配合PWM输出作为信号源二、工作原理2.1 脉宽测量原理以测量高电平脉宽为例1. **设置捕获边沿**首先设置为**上升沿捕获**2. **第一次捕获**上升沿到来时捕获当前CNT值并清零计数器然后将捕获边沿切换为**下降沿**3. **第二次捕获**下降沿到来时再次捕获CNT值4. **计算脉宽**两次捕获之间的计数值 × 计数周期 高电平持续时间2.2 溢出处理当被测脉宽较长时定时器可能发生溢出。需要在中断中对溢出次数进行累加最终高电平时间为高电平时间 (溢出次数 × ARR 最后一次捕获值) × 计数周期2.3 状态变量设计三、硬件连接四、软件设计4.1 STM32CubeMX配置**1. 时钟配置**- 选择外部高速时钟HSE- 系统时钟设为72MHz- APB1总线时钟72MHz定时器时钟源**2. TIM2输入捕获配置**- 通道1输入捕获模式- 预分频器PSC72-1 → 计数频率 72MHz / 72 1MHz1μs/计数- 自动重装载值ARR65535最大计数范围- 计数方式向上计数- 极性上升沿捕获代码中会动态切换**3. 中断配置**- 使能TIM2的捕获中断CC1IE- 使能TIM2的更新中断UIE- 设置合适的优先级**4. USART1配置**- 模式异步通信- 波特率115200- 数据位8- 停止位1- 无校验**5. GPIO配置**- PA0输入模式下拉- PA9复用推挽输出- PA10浮空输入4.2 代码实现**定义全局变量**c/* TIM2捕获状态* bit7: 捕获完成标志* bit6: 已捕获到高电平标志* bit5~0: 溢出次数*/uint8_t TIM2CH1_CAP_STA 0;uint16_t TIM2CH1_CAP_VAL; // 捕获值**定时器溢出中断回调**cvoid HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){if(htim-Instance TIM2){if((TIM2CH1_CAP_STA 0X80) 0) // 还未成功捕获{if(TIM2CH1_CAP_STA 0X40) // 已捕获到高电平{if((TIM2CH1_CAP_STA 0X3F) 0X3F) // 溢出次数达到上限{TIM2CH1_CAP_STA | 0X80; // 标记完成TIM2CH1_CAP_VAL 0XFFFF;}else{TIM2CH1_CAP_STA; // 溢出次数1}}}}}**输入捕获中断回调**cvoid HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){if(htim-Instance TIM2){if((TIM2CH1_CAP_STA 0X80) 0) // 还未完成捕获{if(TIM2CH1_CAP_STA 0X40) // 已捕获到上升沿当前是下降沿{// 捕获完成TIM2CH1_CAP_STA | 0X80;TIM2CH1_CAP_VAL HAL_TIM_ReadCapturedValue(htim2, TIM_CHANNEL_1);// 切换回上升沿捕获准备下一次TIM_RESET_CAPTUREPOLARITY(htim2, TIM_CHANNEL_1);TIM_SET_CAPTUREPOLARITY(htim2, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING);}else // 第一次捕获到上升沿{TIM2CH1_CAP_STA 0;TIM2CH1_CAP_VAL 0;TIM2CH1_CAP_STA | 0X40; // 标记已捕获到高电平// 清零计数器__HAL_TIM_SET_COUNTER(htim2, 0);// 切换为下降沿捕获TIM_RESET_CAPTUREPOLARITY(htim2, TIM_CHANNEL_1);TIM_SET_CAPTUREPOLARITY(htim2, TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING);}}}}**主函数**cint main(void){uint32_t high_time_us 0;HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_TIM2_Init();MX_USART1_UART_Init();// 启动输入捕获使能捕获中断和更新中断HAL_TIM_IC_Start_IT(htim2, TIM_CHANNEL_1);__HAL_TIM_ENABLE_IT(htim2, TIM_IT_UPDATE);printf(Input Capture Test Started...\r\n);while(1){if(TIM2CH1_CAP_STA 0X80) // 完成一次高电平捕获{high_time_us (TIM2CH1_CAP_STA 0X3F); // 溢出次数high_time_us * 65536; // 溢出时间high_time_us TIM2CH1_CAP_VAL; // 最后一次捕获值printf(High level duration: %d us\r\n, high_time_us);TIM2CH1_CAP_STA 0; // 准备下一次捕获}}}五、实验现象将待测信号连接到PA0引脚串口调试助手将打印出测量到的高电平持续时间。**测量范围说明**- 计数频率1MHz每个计数周期1μs- ARR65535单次最大测量时间约65.5ms- 通过溢出计数可测量更长时间**串口输出示例**Input Capture Test Started...High level duration: 1500 usHigh level duration: 2500 us...六、常见问题与注意事项6.1 测量精度问题- 输入捕获的精度取决于计数频率计数频率越高精度越高但测量范围会减小- 可通过调整PSC预分频值在精度和范围之间权衡6.2 信号抖动- 可在TIM_ICInitStructure中设置IC1F滤波器参数对输入信号进行滤波- 滤波器值越大抗干扰能力越强但响应会变慢6.3 中断优先级- 建议将捕获中断优先级设置高于其他非关键中断- 更新中断和捕获中断需要配合工作优先级应合理设置6.4 寄存器错误修复使用TIM_RESET_CAPTUREPOLARITY宏时部分HAL库版本可能存在语法错误。如遇到编译报错请检查该宏定义并删除多余的右括号。七、扩展应用输入捕获功能可广泛应用于- **超声波测距**捕获Echo引脚的高电平时间计算距离- **编码器测速**捕获脉冲间隔计算电机转速- **频率计**通过测量周期计算信号频率- **电容触摸按键**检测充放电时间变化有需要学习嵌入式的欢迎私信入群一起学习

更多文章