想搞清楚超声波测距电路,不能只停留在“买一个模块直接接上”的层面。我见过太多人用过HC-SR04或者类似的一体化模块,接上STM32就能读距离,但一旦想自己设计一个专用的测距方案,比如要测更远的量程、要抗环境噪声、要自己控制发射功率,或者要接入现有硬件系统时,立刻就懵了。原因很简单:现成模块把发射、接收、信号处理全部封装好了,你根本看不到中间环节到底发生了什么。这篇文章我就把整个链路拆开,从声波物理特性、器件选型、发射驱动、接收放大、比较整形,到最后的MCU时间测量,一步一步讲清楚,尽量做到看完能自己画原理图、自己写驱动代码。
1. 测距不只是“发个声再听个响”,先搞懂声波在空气中的脾性
设计电路之前,先得从物理层面理解超声波在空气里是怎么传播的,这决定了后面很多器件选型的方向。测距本质上是时间飞行法,记下声波从发射到碰到目标反射回来被接收的总时间,再乘以声速除以2,就是单程距离。公式本身不复杂,难点在于:回波信号非常微弱,而且声波在传播过程中衰减得厉害。
1.1 频率选择:为什么大家都用40kHz而不是200kHz
空气中的声波衰减系数跟频率的平方成正比,频率越高衰减越狠。40kHz左右的超声波在空气中的衰减系数大约在每米1到3dB这个量级,空气湿度、温度都会影响实际值。如果用200kHz,看起来分辨率更高,但传播不到几米就衰减没了,只适合极短距离或者液体介质场景。所以市面上绝大多数空气测距方案都选40kHz。反过来说,如果是水下测距,因为水对高频声波吸收弱得多,就可以用更高的频率取得更好的分辨率,这个差异得先分清。
频率定了,换能器就好选了。市面上的40kHz压电陶瓷超声波换能器分成发射专用(T)和接收专用(R)两类,它们在结构设计上有明确的侧重。发射型换能器更注重把电信号转化成高强度的声波,接收型更注重把微弱的声压变化转化成电信号,灵敏度更高。电路设计时最好成对购买,比如常见的TCT40-16T和TCT40-16R就是一对。如果你非要拿接收头去发射、或者发射头去接收,也不是完全不能用,但性能会明显变差,不建议这样做。
1.2 回波信号到底有多弱,直接决定接收电路增益需求
发射换能器把电能转换成声能,声波向外扩散,打到目标表面后一部分能量被反射回来,再传播回接收换能器,接收换能器再把声能变回电信号。这个过程中能量经过两次电声转换和两次空气传播衰减,回波信号通常是毫伏级别,甚至远距离时只有几十微伏。接收换能器的接收灵敏度一般用dB表示,典型值在-65dB附近,意思就是输出电压比声压参考值低很多。
我做一个粗略的估算:发射端给换能器加10V左右的脉冲激励,发射声压级大约能到110dB;经过2米距离传播衰减5到10dB,目标反射率打个折再衰减一些,来回一共衰减20dB到40dB,接收端声压就降到70到90dB;配合接收换能器的灵敏度,最后能送到放大器输入端的信号大概在几毫伏到几十毫伏之间。这就很明确了:接收电路需要至少40dB到60dB的电压增益,才能把信号放大到比较器可以稳定判断的电平,也就是几百毫伏到1V以上。
这些物理特性总结起来就一句话:发射端要尽可能提升声压输出,接收端要尽可能降低噪声、提升增益。后面所有电路设计都围绕这两个目标展开。
2. 发射链路设计:怎么把微弱的脉冲变成足够响的“喊话”
发射链路的作用很简单:MCU产生40kHz的方波脉冲串,驱动电路把电压提升到换能器需要的电平,推动压电陶瓷片振动发出超声波。但就这么一个环节,里面有很多容易踩坑的细节。
2.1 驱动方案选型:直接驱动、单管升压、H桥驱动怎么选
发射换能器容性负载特性很明显,典型等效电容在2000pF到3000pF左右,驱动它需要一定的瞬态电流。如果MCU引脚直接驱动,高电平只有3.3V,输出电流也有限,声压会非常弱,有效测距没几米,所以必须加驱动电路。
常用方案有这几种,各有适用场景:
- 单三极管/单MOS管驱动:一个NPN三极管或者N-MOS管,集电极接变压器初级或直接接换能器,基极/栅极接MCU脉冲。结构最简单,成本最低,但是只能单向驱动,声压不对称,效率一般。
- 推挽互补驱动:用一对NPN和PNP三极管构成图腾柱,两个引脚反向控制,输出对称方波,效率较高,适合5V左右的供电。
- 变压器升压驱动:先用推挽电路或单管生成脉冲,然后通过一个高频变压器把电压从5V升到12V甚至更高,压电陶瓷换能器在更高激励电压下能产生更强的声压。这个方案测距效果最明显。
- 专用超声波驱动芯片:比如思为同的系列、或者一些自动化厂商的集成驱动器,功能全但成本高,普通DIY和一般产品项目不太必要。
我自己的项目里选了推挽+变压器升压的组合,供电5V,变压器变比1:10,次级峰值电压能达到40V以上,实测发射声压比直接5V驱动强了一大截,极限测距从不到3米拉到了6米以上。
2.2 脉冲串参数怎么定:发射频率、脉冲个数、间隔时间
MCU发出的脉冲串频率必须是换能器的谐振频率,也就是40kHz,这个不能偏。脉冲个数通常在6到16个之间。个数太少,换能器来不及起振,声波能量不足;个数太多,虽然声波持续更久能量更大,但会拉长发射时间,导致近距离盲区扩大。
计算一下:40kHz一个周期是25微秒,发射10个脉冲共250微秒,这段时间内声波已经走了大约8.6厘米,如果再加上接收电路余振的时间,盲区通常在20到40厘米之间。如果你的应用需要测很近的目标,比如20厘米以内就不能测,那脉冲数要相应减少。但脉冲数少又会导致回波弱,所以这是权衡。
实际设计时,MCU用定时器输出PWM比较合适。我习惯用定时器的主从模式,主定时器控制脉冲个数和间隔,从定时器输出PWM波形,这样CPU基本不参与,整个发射过程占用极少的处理资源。发射完成后开启某个外部中断或者输入捕获,等待接收链路的回波信号。
2.3 变压器绕制参数和注意事项
如果是自制变压器,核心参数是初次级匝数比和工作频率。对于40kHz,变压器磁芯适合用铁氧体罐型磁芯或者EE型小磁芯。初级2到3匝的话次级做20到30匝,变比1:10左右。绕制时有几个实际问题要注意:
- 同名端不要接反,接反了输出波形就变成负压主导,虽然也能响但效率不对。
- 初级线圈的线径不能太细,因为驱动峰值电流可能到1A级别,至少要0.2mm以上。
- 磁芯要开气隙或者用低导磁率材料,否则容易饱和。
- 变压器次级输出端建议并联一个1MΩ左右的电阻给电荷提供泄放回路,否则换能器上容易积累直流偏置,影响稳定性。
我用的是EE13磁芯,初级3匝、次级30匝,反馈绕组不接,驱动频率40.3kHz微调了一下让输出幅度最大,因为实际换能器的谐振频率可能略有偏差,最好上电后用示波器看次级波形幅度来微调频率,幅度最大的点就是实际谐振点。
你看,发射链路其实不只是“给个方波那么简单”,它牵扯阻抗匹配、驱动能力、升压变压器的设计和谐振频率校正。发射效率上去了,回波信噪比才有保证。这就像喊话,你先得喊得够响,对方才听得清。
3. 接收链路设计:微伏级回波怎么一步步变成MCU认识的脉冲
接收链路是整个电路的核心难点,不是因为原理有多复杂,而是因为信号太小、噪声太多,稍不小心就被淹没。完整的接收链路包括前置放大、带通滤波、主放大/自动增益、整形比较几个环节。
3.1 前置放大:第一级放大器决定了整个链路的信噪比天花板
接收换能器的输出阻抗比较高,容性负载特征明显,信号幅度又小,所以第一级放大器必须满足几个硬性条件:输入阻抗要高、等效输入噪声要低、增益要适中、带宽要覆盖40kHz但不需要太高。运放的输入噪声密度和偏置电流是首要指标,不能随便拿个741去测,那种运放自身噪声比信号还大。
可选的低噪声运放像AD797、OP27、LT1037这些都能用,但对40kHz来说其实还有更对口的选择。ADI的AD8099、TI的OPA847这类宽带低噪声运放也可以,不过性能过剩价格偏高。我做实测比较之后,性价比最高的是用TI的OPA365或者OPA2376,GBW 5.5MHz以上、输入电压噪声密度在7.5nV/√Hz左右,增益做到40dB没问题,而且单电源供电还能保持输出接近轨到轨。如果你手头只有LM358这类通用运放,也不是完全不能用,只是噪声会大一些,近距离还行,远距离回波会很难分辨。
第一级电路拓扑用同相放大,输入直接接接收换能器正极,换能器负极接地,输入端到地接一个1MΩ的偏置电阻,同相端还需要通过电阻分压给一个半电源偏置。增益设计在100倍左右也就是40dB,这样几毫伏的输入信号放大到几百毫伏。第一级放大器的反馈电阻大小会影响带宽,我用的是10kΩ和100Ω的搭配,增益101倍,带宽足够覆盖40kHz且高频噪声不至于放得太大。
3.2 带通滤波:把40kHz附近的有用信号“捞”出来
环境噪声频谱很宽,日光灯、电机、空气流动都会产生干扰,其中低频成分尤其强。如果不过滤直接放大,电路很容易产生虚假触发。带通滤波器的中心频率就是40kHz,带宽窄一点更好,但Q值太高又会导致响应慢,接收信号到来后建立稳定输出需要更长时间,近距离响应会变差。
带通滤波设计有两种常用路径。第一种是无源LC带通,电容电感选型不方便,频率偏低时电感体积又大,在40kHz这个频段不太划算。第二种是有源RC带通,运放加几个电阻电容就能实现,多路负反馈或Sallen-Key拓扑都行。我选用的是多路负反馈带通滤波器,中心频率40kHz,Q值约8到10,通带带宽4到5kHz。这个带宽既能较好地抑制带外噪声,也不会对40kHz脉冲串的包络造成太大畸变。
有源滤波器的运放同样需要低噪声、足够带宽,增益带宽积至少要几MHz才行。为了减少温漂影响,电阻选1%精度的金属膜电阻,电容选C0G或者NPO材质的,这个频段用X7R问题也不大,但C0G更稳。
滤波放在放大器前面还是后面,这是个关键决策。我的建议是前置放大和带通滤波分开做:第一级放大40dB,紧接着做带通滤波,然后如果增益不够再补一级放大。这样低频干扰不会在第一级就被放大到饱和,同时第二级放大的是经过滤波的有用信号,信噪比更好。有些设计把带通滤波放到第一级前面,好处是抗干扰最强,但信号太小的时候滤波器的插损和噪声会恶化信噪比,不是最优解。
3.3 主放大级与自动增益控制:远近距离都能稳定检测
经过两级放大之后,近距离回波可能已经到伏特级,而远距离回波只有几百毫伏甚至更低。如果固定增益,近距离信号过大容易让后级饱和,远距离信号又不够触发比较器。这时候就需要自动增益控制,让电路的增益随回波信号幅度自动调整。
实现的方案有几种:用数字电位器改变反馈电阻、用模拟乘法器、用JFET作为压控电阻。对40kHz信号来说,JFET压控电阻方案简单可靠。我在放大器的反馈回路里串联一个N沟道JFET(比如2SK30ATM),用检波电路检测输出幅度,幅度越大,经过反馈控制电路输出的控制电压越负,JFET的导通电阻越大,放大器增益越低。这样形成一个负反馈回路,自动把输出稳定在一个合适的电平范围内。
说了这么多,可能有人觉得“我一个人做项目不需要这么复杂”。确实,如果测距范围只在0.5到3米,做固定增益就够了,增益调到60dB,后级比较器用滞回比较就不会有问题。但如果想测5米、6米以上,或者目标反射率变化很大,自动增益就非常有必要。我在自己的方案里做了AGC,实测下来近距离2厘米到6米都能稳定检测,比起固定增益方案的近距饱和远距触发不了的情况,体验完全是两回事。
3.4 比较器整形:把模拟回波变成干净的数字脉冲
比较器的输入是经过放大滤波的模拟回波信号,输出一个高电平脉冲给MCU。这里最大的坑是“振铃”。回波信号是包络形状的,信号幅度超过阈值时输出高电平,低于阈值时输出低电平,如果阈值设置得太低,噪声尾巴会产生多次触发,MCU拿到一堆乱脉冲。解决方法是加滞回比较,也就是阈值的上升和下降不是同一个值,迟滞窗口宽度可以根据信号幅度调整,一般设置在50到200mV。
比较器的选型要考虑传输延迟和输出类型。TLV3501是高速比较器,4.5ns延迟,轨到轨输出,可以直接接MCU,不放心的话加个10kΩ上拉电阻。如果只是做普通的40kHz测距,用LM393或者TL3116这类常见比较器也够用。我实际用了TLV3501,输出波形非常干净,这点在长距离微弱信号场景尤其重要,因为信号幅度小,噪声稍微触发一次就会引起距离跳变。
如果不想用比较器,也可以把放大后的信号直接送进MCU的ADC周期采样,用软件做峰值检测或者FFT处理。这个方案的优点是可以在数字域做更复杂的滤波和算法,对硬件链路的要求降低一些,但代价是MCU的采样率要足够高。STM32F103的ADC最高采样率1Msps,对40kHz信号来说,一个周期能采25个点,做峰值检测还是可以的,但程序复杂度上去了。我建议初学者还是用比较器方案,简单可靠,后面再慢慢改成ADC方案做增强功能。
4. STM32的时间测量与数据处理:别让精度死在后端
前面硬件链路输出的是一路脉冲信号,宽度或者相位跟飞行时间相关,剩下的工作就是MCU准确测量时间、计算距离、排除干扰。
4.1 输入捕获还是外部中断:为什么输入捕获更稳
STM32的定时器输入捕获可以直接测量脉冲宽度,精度到微秒甚至亚微秒级别。以STM32F103的72MHz定时器时钟来说,一个计数周期约13.9纳秒,40kHz一个周期约25000纳秒,也就是说一个声波周期大约1800个计数。用输入捕获模式测量回波脉冲的上升沿和下降沿之间的间隔,换算成距离分辨力可以达到零点几毫米级别,当然实际分辨力受换能器带宽和声速波动限制,没这么夸张,但时间测量的精度本身是足够高的。
外部中断也能测,但软件执行延迟不稳定,中断触发后进入中断处理到启动定时器读数之间的时间抖动可能达到几微秒甚至十几微秒,换算成距离就是几个毫米到几个厘米的误差,而且抖动随机,无法校准。所以正经设计肯定用输入捕获,把测量交给硬件,软件只做解读。
4.2 声速补偿:温度才是最大的误差来源
距离计算公式是d = v × t / 2,v是声速。很多人直接写v=340m/s,这在15℃左右误差不大,但在夏天40℃环境和冬天-10℃环境下声速差多少呢?用公式v = 331.4 + 0.6×T估算,40℃时声速355.4m/s,-10℃时325.4m/s,相差约30m/s,也就是将近10%的误差。测3米距离时,误差可能到30厘米,完全不可接受。
所以做实用超声波测距,温度补偿是标配。方案很简单:板上放一个DS18B20或者NTC热敏电阻,测到环境温度后实时修正声速。代码里维护一个函数,输入温度输出声速,每一轮测距时调用一次。如果对精度要求更高,还要考虑空气湿度和气压的影响,但对一般民用场景,温度补偿已经能覆盖90%以上的误差来源。
4.3 滤波算法:单次测量值根本不能用
超声波回波信号受环境干扰、目标形状、目标角度的影响巨大,单次测量结果经常有跳变。即使电路层面做了滤波,数字端也建议加上均值滤波或者中值滤波。我的做法是连续测5次,去掉最大值最小值,剩下3次取平均,这样一可以减少随机误差,二可以滤掉偶发性的尖峰干扰。对于运动目标的应用,这个延迟大约50到100毫秒,完全能接受;如果要求快速响应,可以改成滑动窗口均值滤波,窗口大小根据场景调。
另外,测距结果超过预定最大量程时,比如超过5米还没收到回波,MCU要能正确处理超时。发射脉冲后启动定时器,如果超过一个最大往返时间比如40毫秒,那肯定没有回波或者目标太远,这时直接返回无效值,不要卡在等待状态。处理这一步对系统稳定性很重要,尤其适合连续扫描的应用场景。
5. 实测调通:那些图纸上画不出来、但真机一定会遇到的问题
电路从原理图到PCB再到点火调试,一定会遇到各种意料之外的问题。这里把我实际踩过的坑整理成清单,按优先级从高到低列出来,希望能帮大家少走弯路。
5.1 收发串扰和“余振”造成的近距离盲区
发射脉冲结束后,发射换能器不会立刻停止振动,而是有余振;同时收发换能器如果安装位置太近,声波和振动会直接通过结构和空气耦合到接收端。这两者叠加起来,表现为接收端在发射结束后一小段时间内依然能检测到一个较大的信号,看起来像极近距离的回波。这个现象就是近距盲区的根源。
处理办法有几种,可以组合使用。首先是硬件上,发射和接收换能器之间加隔声屏障,我用的是在PCB上开槽加一个硅胶垫隔开,效果明显。然后是电路上,在发射瞬间到回波到达前的这段时间,让接收链路衰减——做法是在前置放大器的耦合电容处放一个模拟开关,发射时开关导通把放大器的输入端短接到地,发射结束后释放。不过我后来发现用软件也能实现类似效果,就是发射结束后的前1毫秒内,MCU不对接收脉冲做响应,直接忽略。单纯软件方案简单,但代价是近距离的直接盲区就被拉大了,配合硬件隔声之后软件屏蔽时间可以缩短到0.5毫秒左右,对应盲区大约17厘米。
5.2 示波器实测:如何判断放大链路是否真的在正常工作
调试接收链路时,示波器探头不要接在比较器输出上瞎猜,要从前往后逐级排查。先把探头换成10x档,接在接收换能器两端,发射脉冲后观察有没有微弱的衰减振荡波形;如果没有,检查发射是否正常、换能器是否接反。然后再移到前置运放输出端,看波形幅度有没有放大到几百毫伏。逐级看下来,哪个环节没有信号就知道问题出在哪。
有一点必须是示波器的触发源设为发射脉冲边沿,然后用单次触发模式抓回波。因为回波是一次性的瞬态信号,自由运行模式下画面会闪得看不清。把时间轴拉开到10ms或者20ms一屏,水平位置配合触发延时,能看到完整的发射-回波时间差。我曾经因为忘记切换单次触发,看了半天都以为电路没输出,这事千万别再犯。
5.3 PCB布局走线:模拟小信号电路最容易在案板上翻车
接收信号是微伏到毫伏级别,发射驱动是几十伏、峰值电流安培级别的脉冲,这两者在同一块板上共存,布局走线做不好,接收链路会被发射脉冲和电源纹波干扰得根本没法用。
我的布局原则是这样:发射驱动电路和变压器放板子的一角,接收放大链路放另一角,中间用地线带或者大面积铺铜隔开。接收链路的地要和发射驱动的地分开走,最后在电源输入端单点汇合,不要形成地环路。电源要从供电入口处先经过一个磁珠或者10Ω电阻再分配给接收放大电路,再并联一个100nF和10μF电容到地。接收换能器的信号走线尽可能短且远离数字信号线,尤其是晶振引线和MCU的IO线。如果板子面积允许,接收放大区域的正反面都铺地铜,过孔稀疏打几个连接地平面就行。
因为在案板上飞线调试的时候,那真是“满屏噪声、寸步难行”。一旦把布局规则做对,很多莫名其妙的干扰、误触发、距离跳动就自己消失了。EMC这块不是玄学,是好布局的自然结果。
5.4 换能器指向性和目标反射率的工程现实
实测下来你会很快发现:对着平整墙面测,距离很准很稳定;但对着一个圆角椅子腿、或者一盆绿植测,读数就开始跳了。这不是电路故障,而是超声波测距本身的物理局限。换能器有指向性,发射和接收波束角一般在60度到80度之间,目标表面跟声波束不垂直时反射能量急剧下降,表面粗糙散射强的目标也一样。
工程上有几个应对思路。一个是多换能器阵列,用两三个接收头分开放置,哪个信号强用哪个,覆盖更广的角度。另一个是调整阈值和AGC参数,牺牲一些灵敏度来换稳定性。还有一个是不能忽略的:安装时尽量让换能器平面垂直朝向需要测的物体表面,很多“测不准”其实只是安装角度不对,跟电路完全无关。
对于反射率这个问题,我有个教训:之前拿超声方案去测篮球,近距离还行,距离一远,因为球面反射让回波散开,信号根本收不回来。后来换了更大的换能器,还是不太理想。所以选型之前一定要想清楚目标物是什么材质、什么形状、反射特性如何,这比纠结电路设计更重要。
6. 进阶方向:还能把超声波测距用到什么程度
如果你已经把基础电路跑通,距离显示稳定了,可以沿着下面的方向继续深入,每个方向都能让这套方案的价值打一个滚。
6.1 从单点测距到扫描成像
把换能器固定在一个舵机或者步进电机上,每转一个角度测一次距离,就能合成出一圈的环境距离数据,也就是2D雷达。这个玩法在扫地机器人、AGV避障里已经大量使用。硬件改动不大,关键是数据融合算法和驱动时序要处理好。我用一个SG90舵机加之前做好的测距板子做了一个360度扫描的桌面雷达,配合上位机画出来的轮廓图,效果非常直观。
6.2 多通道并行测距
如果应用需要同时测好几个方向的距离,可以布置多个接收换能器配一个发射头,或者多对换能器轮流工作。这样硬件成本增加不多,但MCU的资源开销和时序调度要重新设计。我做过一版双通道方案,两个接收通道交替启用,测量周期压缩到60ms以内,已经能支撑一些轻型移动机器人的避障需求。
6.3 数字信号处理方向
如果不想被模拟AGC的复杂度限制住,可以考虑把放大后的模拟信号直接送MCU的ADC进行数字解调。用数字方法做相关运算或者Goertzel算法提取40kHz频点能量,可以省掉比较器和部分滤波器,而且算法可以不断迭代优化。STM32F4或者更高性能的MCU跑起来毫无压力。这个方向适合软件能力比较强、想往嵌入式信号处理走的开发者。
做个简单的成本估算,基础方案的物料成本:一对换能器大约几块钱,运放和比较器加起来十几块钱,MCU用STM32F103C8T6差不多几块钱,所有阻容加上PCB批量做,整套成本能压到二三十块钱以内。比起动辄上百的现成工业测距模块,自己做出来的东西虽然折腾,但换来的是对每个环节的理解和自主定制能力,这笔账怎么算都不亏。