第四节:STM32定时器(3.输入捕获:从HC-SR04到多传感器融合测距) 1. 从HC-SR04到多传感器融合测距第一次用STM32的输入捕获功能做超声波测距时我盯着那个不断跳动的数值看了整整半小时——就像第一次用万用表量电压的小学生。但当我尝试把红外、激光传感器数据加进来时问题突然变得有趣起来。想象一下你的智能小车正以0.5米/秒的速度冲向墙壁单独依赖超声波就像蒙着一只眼睛走路可能错过细小障碍物也可能被声波反射干扰。这就是为什么我们需要多传感器融合测距。HC-SR04超声波模块的工作原理就像蝙蝠回声定位Trig引脚发出10μs的高电平脉冲触发测距Echo引脚会在接收到回波时输出高电平。用定时器捕获这个高电平持续时间t距离d340m/s×t/2声速取340m/s。但实际调试时会发现当测量角度超过30度或者遇到毛绒玩具这类吸音材料数据就开始飘忽不定。这时候加入GP2Y0A21红外测距传感器就像给系统装了第二只眼睛。它的三角测量原理对漫反射表面更敏感有效距离10-80cm正好弥补超声波在近距离的死角。我在实验中发现把红外传感器安装在超声波模块旁边两者数据互补能覆盖更多场景。比如检测玻璃门时超声波可能直接穿透而红外却能可靠返回数据。2. 定时器多通道输入捕获实战要让STM32同时处理多个传感器信号就像让一个厨师同时照看几口锅。以TIM2为例它有4个独立捕获通道配置关键点在于时钟基准统一和中断优先级管理。下面这段配置代码展示了如何初始化两个捕获通道// TIM2通道1配置超声波Echo TIM_ICInitTypeDef TIM2_IC1; TIM2_IC1.TIM_Channel TIM_Channel_1; TIM2_IC1.TIM_ICPolarity TIM_ICPolarity_Rising; TIM2_IC1.TIM_ICSelection TIM_ICSelection_DirectTI; TIM2_IC1.TIM_ICPrescaler TIM_ICPSC_DIV1; TIM_ICInit(TIM2, TIM2_IC1); // TIM2通道2配置红外输出 TIM_ICInitTypeDef TIM2_IC2; TIM2_IC2.TIM_Channel TIM_Channel_2; TIM2_IC2.TIM_ICPolarity TIM_ICPolarity_Falling; TIM2_IC2.TIM_ICSelection TIM_ICSelection_IndirectTI; TIM_ICInit(TIM2, TIM2_IC2);实际调试时有个坑当两个传感器信号同时到达时普通中断处理会导致数据覆盖。我的解决方案是用DMA双缓冲模式将捕获值直接存入内存。具体操作是开启TIM2的DMA请求设置循环模式的双缓冲区。这样即使主程序正在处理上一组数据新数据也会自动存入备用缓冲区。对于更复杂的场景比如需要同时处理超声波、红外和激光TOF传感器我会启用定时器的从模式Slave Mode。把TIM2设为主定时器TIM3设为从定时器通过ITRx信号同步启动。这样所有传感器的计时基准完全一致后续数据融合时不需要做时间对齐补偿。3. 多源数据融合算法实现拿到多个传感器的原始数据后真正的挑战才开始。去年给智能小车升级避障系统时我试过三种融合方案加权平均、卡尔曼滤波和决策级融合。最终选择取决于你的应用场景和对实时性的要求。最简单的加权平均法适合新手快速上手。比如超声波权重设为0.6红外0.3激光0.1根据传感器精度动态调整。代码实现就三行float distance_fused 0.6*ultrasonic_dist 0.3*infrared_dist 0.1*tof_dist;但当小车在走廊快速移动时这种方法会产生乒乓效应——数据在两组传感器结果间来回跳变。这时候卡尔曼滤波就是更好的选择。我用STM32F4的FPU加速计算将每个传感器建模为一个独立观测源。关键是要合理设置过程噪声Q和观测噪声R我的经验值是超声波Q0.01, R0.1红外Q0.05, R0.3激光TOF Q0.001, R0.01最复杂的决策级融合适合对可靠性要求高的场景。比如设置超声波为主传感器当检测到其数据突变时可能遇到玻璃自动切换红外数据为主。我在代码中实现了状态机typedef enum { NORMAL_MODE, // 超声波主导 GLASS_MODE, // 红外主导 EDGE_MODE // 激光TOF主导 } SensorFusionMode;4. 性能优化与抗干扰设计在多传感器系统中电磁干扰就像无处不在的背景噪音。有一次调试时电机启动导致超声波测距值突然增加20cm。通过示波器抓取波形发现电机的PWM噪声通过电源线耦合到了传感器电路。最终用以下方案解决问题硬件层面每个传感器电源加π型滤波10μF100nF电容信号线套磁环超声波模块的Trig和Echo走线包地软件层面在捕获中断中增加数字滤波#define FILTER_DEPTH 5 static uint16_t dist_buffer[FILTER_DEPTH]; uint16_t filtered_distance(uint16_t raw) { static uint8_t index 0; dist_buffer[index] raw; if(index FILTER_DEPTH) index 0; uint32_t sum 0; for(uint8_t i0; iFILTER_DEPTH; i) { sum dist_buffer[i]; } return (uint16_t)(sum/FILTER_DEPTH); }设置信号有效性检查如超声波最大返回时间对应8m距离定时器配置也有讲究测量超声波时预分频器设为711MHz计数频率这样每个计数对应1μs时间而红外传感器只需要100μs分辨率预分频器可以设为720010kHz计数频率。不同通道采用不同分频会引入时间基准差异这时候需要在数据融合环节做归一化处理。最后分享一个调试技巧用定时器的PWM输出功能模拟传感器信号。比如配置TIM4_CH1输出40kHz方波超声波模块工作频率用跳线连接到TIM2的捕获通道。这样无需实际移动障碍物就能验证算法逻辑大大节省开发时间。