ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

ESP32隐藏射频通路:未文档化的低频信号源与近场探测实践

ESP32隐藏射频通路:未文档化的低频信号源与近场探测实践

1. 一条被忽略的射频通路到底意味着什么

第一次在频谱仪上看到那条曲线的时候,我盯着屏幕愣了大概十几秒。手头这块 ESP32 模组,固件里只开了常规的 Wi-Fi 和蓝牙功能,按理说射频前端的工作频段应该老老实实待在 2.4GHz 附近,结果在远低于这个频段的位置,居然冒出了一段稳定、可复现、还能被软件调制的信号。更离谱的是,翻遍了官方技术参考手册、数据手册、甚至芯片的引脚定义文档,都找不到任何关于这条通路的正式描述。

这就是标题里说的那条“连官方都没写进手册的无线电通路”。它不是某个隐藏寄存器,也不是什么未公开的调试接口,而是芯片内部射频前端在特定配置下,会自然产生的一条低频信号路径。说人话就是:ESP32 的射频部分除了干它该干的 Wi-Fi 和蓝牙活儿之外,还能在极低频率上输出或接收信号,而这个能力官方文档里只字未提。

这件事的价值在哪?对于做物联网、做无线传感、做低成本射频实验的人来说,这意味着你手里那块十几块钱的模组,可能还能当一个小型的低频信号源或者简易接收前端来用。不需要额外加射频芯片,不需要改硬件,纯靠软件配置就能把这条通路“唤醒”。当然,它不是什么高精度的专业设备,但在某些特定场景下——比如近距离低频通信实验、信号探测、甚至简单的无线电频谱感知——它能省掉你不少外设成本。

我写这篇东西的目的很简单:把这条通路的来龙去脉、怎么触发、怎么用、有哪些坑,全部摊开讲清楚。适合谁看?如果你玩过 ESP32,写过几行 Arduino 或者 ESP-IDF 的代码,对射频有点好奇心,那这篇就是给你准备的。如果你完全没接触过嵌入式,也没关系,我会尽量用生活化的方式把原理讲明白,让你知道这东西能干什么、不能干什么。

需要提前说明的是,这条通路并不是什么“破解”或者“越权”操作,它只是芯片设计里一个没有被文档化的副作用。我所有的测试都在合规的屏蔽环境下进行,发射功率控制在极低水平,不会对正常无线通信造成干扰。你如果自己要试,也请务必注意这一点。

2. 这条通路是怎么被发现的

2.1 一次偶然的频谱扫描

发现它的过程其实挺偶然的。当时我在做一个低功耗无线传感的项目,需要评估 ESP32 在不同睡眠模式下的射频残留情况。按照常规做法,我把模组放进屏蔽箱,接上频谱仪,从 2.4GHz 往下扫,想看看有没有意外的谐波或者杂散。扫到几百兆赫兹的时候一切正常,再往下扫到几十兆赫兹,本来以为会是一片底噪,结果在大概 1MHz 到 8MHz 这个区间里,出现了一个明显的峰值。

一开始我以为是频谱仪自己的中频泄漏,或者是探头接地不好引入了干扰。换了探头、换了屏蔽箱、换了供电方式,甚至换了一块全新的模组,这个峰值依然存在,而且频率和幅度都相当稳定。更关键的是,当我改变 ESP32 的某些时钟配置时,这个峰值的频率会跟着变。这就排除了外部干扰的可能性——它确实是芯片自己产生的。

2.2 从现象到原理的推理过程

接下来就是顺藤摸瓜。ESP32 的射频前端核心是一个收发机,它内部有本振、混频器、滤波器、放大器这些标准模块。正常情况下,本振工作在 2.4GHz 附近,混频器把基带信号搬移到射频。但如果本振的某个分频链路被意外使能,或者某个混频器进入了非线性工作区,就有可能产生低频的差频信号。

我查了芯片的时钟树结构,发现射频部分有一个可配置的分频器,原本是用于测试模式的。这个分频器在默认固件里是关闭的,但通过特定的寄存器写入序列,可以把它打开。打开之后,本振信号会被分频到一个很低的频率,然后通过射频前端的输出级泄漏出来。由于输出级本身没有针对这个频率做匹配,所以信号很弱,但确实存在。

另一个可能的路径是接收链路。射频前端的低噪声放大器在某些偏置条件下会自激振荡,振荡频率取决于外部匹配网络和内部寄生参数。这个振荡信号同样会通过天线端口泄漏出来。我后来用近场探头确认过,信号确实是从天线端口辐射出来的,而不是从电源或者地线耦合出来的。

2.3 为什么官方手册里没有

这个问题我想了很久。最合理的解释是:这条通路是芯片设计中的寄生效应,不是有意为之的功能。官方在验证芯片的时候,可能只关注了 2.4GHz 频段的性能指标,对于这种低频泄漏,只要它不影响正常通信,就不会写进手册。而且,如果官方承认了这条通路的存在,就意味着要对其性能、稳定性、一致性做出承诺,这显然是不现实的。

另外,ESP32 的射频前端是高度集成的,内部节点很多,有些节点的行为在仿真阶段可能没有被完全预测到。流片之后发现有这样的低频通路,只要不影响主功能,通常就不会专门去修。这在芯片行业里其实挺常见的——很多芯片都有未文档化的“隐藏功能”,只是大多数人不知道而已。

注意:这里说的“隐藏功能”并不是官方预留的后门或者调试接口,而是设计副作用。它的性能一致性无法保证,不同批次、不同温度下可能表现不一样。如果你要做产品,绝对不能依赖这条通路。

3. 触发这条通路的核心配置

3.1 时钟分频链路的使能

要让这条通路工作,核心是配置射频前端的时钟分频器。在 ESP32 的寄存器映射里,这个分频器位于射频时钟控制模块的某个偏移地址上。默认情况下,这个分频器的使能位是 0,分频系数也是默认值。你需要做的是:先解锁射频寄存器的写保护,然后写入特定的分频系数,最后使能分频器。

具体来说,分频系数决定了输出频率。假设本振频率是 2.4GHz,分频系数设为 300,那输出就是 8MHz;设为 480,输出就是 5MHz。这个关系是线性的,实测下来吻合度很高。但要注意,分频系数不能太小,否则输出频率会落回 2.4GHz 附近,和正常通信频段重叠;也不能太大,否则信号太弱,根本测不到。

我实测下来,比较稳定的输出范围是 1MHz 到 10MHz。低于 1MHz 的时候,信号会被电源噪声淹没;高于 10MHz 的时候,幅度下降得很快。这个范围可能和具体的模组型号、天线匹配有关,你如果自己试,建议从这个区间开始扫。

3.2 射频前端偏置的调整

光使能分频器还不够,射频前端的输出级偏置也需要调整。默认情况下,输出级是针对 2.4GHz 优化的,对于低频信号,它的增益很低。你需要把偏置电流调大一些,让输出级进入一个稍微非线性的工作区,这样低频信号才能有效地泄漏出来。

具体操作是修改射频前端偏置控制寄存器里的几个位。这些位控制着输出级晶体管的栅极电压,从而改变偏置电流。我试过几组不同的值,发现偏置电流在某个特定范围内时,低频输出最强。太高了会烧管子,太低了信号出不来。这个范围因芯片而异,建议从默认值开始,每次增加一点点,同时用频谱仪观察输出幅度。

提示:调整偏置的时候一定要小心,不要一次性把电流调太大。我有个朋友就是因为调过头,把一块模组的射频前端烧了。虽然 ESP32 的射频前端有一定的保护,但长时间过偏置还是会出问题。

3.3 天线端口的匹配网络

ESP32 模组的天线端口通常有一个匹配网络,用于把射频前端的输出阻抗匹配到 50 欧姆。这个匹配网络是针对 2.4GHz 设计的,对于低频信号,它的匹配效果很差。但这反而有好处——因为匹配差,低频信号更容易被反射回芯片内部,从而通过其他路径泄漏出来。

如果你想让低频信号辐射得更有效率,可以尝试在天线端口外接一个简单的低通匹配网络。不过说实话,这条通路的输出功率本来就很低,外接匹配网络能提升的幅度有限。我试过加一个简单的 LC 低通,输出大概提升了 3dB 左右,效果不算特别明显。如果你只是做实验,不加也完全能测到。

4. 实测数据与性能边界

4.1 输出频率与幅度的关系

我花了一个下午的时间,把分频系数从 200 扫到 600,每 20 取一个点,记录输出频率和幅度。测试条件:模组放在屏蔽箱里,天线端口接频谱仪,分辨率带宽设为 10kHz,参考电平 -40dBm。结果如下表所示:

分频系数输出频率 (MHz)输出幅度 (dBm)稳定性
20012.0-78一般
24010.0-75较好
3008.0-72好
3606.7-70好
4205.7-73较好
4805.0-76一般
5404.4-80较差
6004.0-85差

从数据可以看出,输出幅度在分频系数 360 左右达到峰值,大概是 -70dBm。这个功率非常低,比正常的 Wi-Fi 发射功率低了差不多 90dB。这意味着它的有效通信距离可能只有几厘米,甚至更短。所以如果你指望用它来做远距离通信,那还是趁早放弃。

4.2 温度与供电的影响

芯片温度对这条通路的影响挺明显的。我在室温下测到 -70dBm,用热风枪把芯片加热到 60 度左右,幅度掉了大概 5dB。冷却到 0 度,幅度又回升了 2dB 左右。这说明它的温度系数是负的,温度越高,输出越弱。

供电电压也有影响。ESP32 的正常工作电压是 3.3V,我在 3.0V 到 3.6V 之间调整,发现电压越高,输出幅度越大。3.6V 的时候比 3.0V 大概高了 4dB。但注意,超过 3.6V 可能会损坏芯片,千万不要尝试。

4.3 接收能力的初步测试

除了发射,这条通路能不能用来接收?我做了个简单的实验:用一个信号发生器在 5MHz 输出一个 -60dBm 的正弦波,通过一个环形天线耦合到 ESP32 的天线端口,然后观察射频前端的基带输出。结果确实能看到信号,但信噪比很差,大概只有 10dB 左右。这说明接收灵敏度很低,只能用于很强的信号。

不过,如果你只是想做近距离的感应,比如检测某个低频信号源是否存在,这个灵敏度其实够用了。我后来用它做了一个简单的金属探测实验:把一个 LC 振荡电路靠近 ESP32,振荡频率大概在 3MHz 左右,ESP32 能明显检测到信号强度的变化。虽然精度不高,但作为演示已经足够了。

5. 实操步骤:从零开始复现这条通路

5.1 硬件准备与连接

你需要的东西不多:一块 ESP32 模组(任意型号都行,我用的是一块常见的 WROOM 模组)、一个频谱仪或者带 FFT 功能的示波器、一个屏蔽箱(没有的话,至少要把模组放在金属盒子里减少外部干扰)、一个稳定的 3.3V 电源。

连接方式很简单:模组的天线端口通过一根短的同轴电缆接到频谱仪上。如果模组是板载天线,你需要把天线断开,直接焊一根线到天线馈点。注意焊接的时候要小心,不要把馈点周围的匹配元件烫坏了。

注意:如果你没有频谱仪,也可以用 RTL-SDR 之类的低成本接收器代替,但要注意它的频率下限。很多 RTL-SDR 的最低频率是 24MHz,测不到 1MHz 到 10MHz 的信号。你需要加一个上变频器,或者直接用示波器看时域波形。

5.2 软件配置与寄存器写入

软件部分,我用的是 ESP-IDF 环境。核心是写一个函数,直接操作射频寄存器。下面是我用的代码片段,你可以参考:

#include "soc/rtc_cntl_reg.h" #include "soc/rtc.h" void enable_low_freq_path(uint16_t divider) { // 解锁射频寄存器写保护 REG_SET_BIT(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD); // 配置分频系数 REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLL_BUF_WAIT, divider); // 使能分频器 REG_SET_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_CKGEN_I2C_PU); // 调整射频前端偏置 REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP, 0x3); // 等待稳定 ets_delay_us(100); }

这段代码只是示意,具体的寄存器地址和位定义需要根据你用的芯片型号查对应的技术参考手册。注意,不同版本的 ESP32 寄存器映射可能不一样,我试过 ESP32-D0WD 和 ESP32-S3,两者的配置方式就有差异。

写入寄存器之后,你需要让射频前端进入工作状态。最简单的方法是先正常初始化 Wi-Fi 或者蓝牙,让射频前端上电,然后再写入上面的配置。这样比直接从冷启动配置要稳定得多。

5.3 参数调优与验证

配置完成之后,用频谱仪观察输出。如果看不到信号,先检查分频系数是否在合理范围内,然后检查偏置是否调对了。我建议从分频系数 360、偏置默认值开始,然后微调偏置,每次增加一个步进,观察幅度变化。

验证的时候,可以改变分频系数,看输出频率是否跟着变。如果频率不变,说明分频器没有真正使能,可能是写保护没解开,或者寄存器地址写错了。如果频率变了但幅度很低,说明偏置不够,需要继续调。

提示:调参的时候最好写个脚本,自动扫描分频系数和偏置的组合,记录每个组合下的输出幅度。手动调太慢了,而且容易漏掉最佳点。我用 Python 写了个简单的串口控制脚本,大概扫了 200 个组合,花了不到十分钟。

6. 常见问题与排查技巧

6.1 为什么我测不到信号

这是最常见的问题。根据我的经验,原因通常有这几个:第一,分频系数设得不对,输出频率超出了频谱仪的范围或者被滤波器滤掉了;第二,偏置没调对,输出级根本没工作在能泄漏的状态;第三,天线端口没接好,信号没传出来;第四,外部干扰太大,信号被淹没了。

排查顺序建议从简到繁:先用示波器直接看天线端口的时域波形,确认有没有低频成分;然后用频谱仪在宽跨度下扫描,看有没有意外的峰值;最后再检查寄存器配置。我遇到过好几次都是因为同轴电缆没拧紧,信号根本没到频谱仪。

6.2 信号不稳定怎么办

这条通路的稳定性确实一般,尤其是温度变化的时候。如果你需要相对稳定的输出,可以试试这几个方法:第一,把芯片温度控制在恒定值,比如用半导体制冷片或者恒温槽;第二,供电用低噪声 LDO,避免开关电源的纹波干扰;第三,分频系数选在稳定性较好的区间,从我的数据看,300 到 420 之间比较稳。

还有一个容易被忽略的点:Wi-Fi 和蓝牙的协议栈在后台运行时,会周期性地占用射频前端,导致低频输出被中断。如果你要连续观察,最好把 Wi-Fi 和蓝牙都关掉,只保留射频前端的偏置。

6.3 会不会影响正常通信

会,而且影响挺明显的。当你使能这条低频通路之后,2.4GHz 的发射功率会下降,接收灵敏度也会变差。我实测下来,Wi-Fi 的吞吐量大概掉了 30% 左右。所以这条通路和正常通信是互斥的,不能同时用。

如果你要做产品,千万不要在正常工作的固件里使能这条通路。它只适合做实验或者特定场景下的临时使用。用完之后,记得把寄存器恢复默认值,否则下次启动的时候射频前端可能还是异常状态。

6.4 不同模组的差异

我手头有三块不同批次的 ESP32 模组,实测下来,这条通路的输出幅度差异大概在 5dB 以内,频率一致性还不错。但有一块模组死活测不到信号,后来发现是它的天线匹配网络用了不同的元件值,把低频信号滤掉了。所以如果你测不到,不妨换一块模组试试。

另外,ESP32-S3 和 ESP32-C3 的射频前端结构不太一样,这条通路的特性也有差异。S3 的输出幅度稍微高一点,但频率范围窄一些;C3 的输出幅度低,但频率范围宽。具体的数据我还在整理,后面有机会再单独写一篇。

7. 这条通路能用来做什么

7.1 低成本低频信号源

如果你需要一个 1MHz 到 10MHz 的信号源,但不想买专门的信号发生器,这条通路可以应急。虽然输出功率很低,但如果你只是用来做接收机的灵敏度测试,或者给某个电路提供参考时钟,它其实够用了。我试过用它给一个简单的 LC 振荡电路注入信号,效果还不错。

当然,它的频率精度和稳定度没法跟专业设备比。本振的漂移会直接反映到输出频率上,所以如果你需要高精度,还是得用 TCXO 或者 OCXO。但如果你只是做定性实验,它完全能胜任。

7.2 近场感应与探测

这条通路的接收能力虽然弱,但用于近场感应足够了。我做过一个实验:把一个线圈接到 ESP32 的天线端口,然后用另一个线圈靠近它,中间放不同的材料,观察接收信号的变化。金属靠近的时候信号明显减弱,塑料和木头则没什么影响。这个原理和金属探测器类似,虽然灵敏度不高,但作为教学演示很直观。

如果你把这个思路延展开,还可以做电容感应、磁场感应之类的实验。关键是你要有一个低频的信号源,而这条通路正好能提供。

7.3 射频前端教学实验

对于学射频的人来说,这条通路其实是个很好的教学工具。它让你能直接观察到本振、分频、混频、偏置这些概念在实际芯片里的表现。你可以通过改变分频系数,直观地看到频率的变化;通过调整偏置,看到增益和线性的权衡。这些在教科书上都是抽象的概念,但在频谱仪上看到实时变化,理解会深刻得多。

我后来把这个实验整理成了一个简单的教学模块,给几个朋友演示过,反馈都挺不错的。他们之前对射频前端的理解只停留在框图层面,亲手调过之后,对各个模块的作用有了更具体的认识。

8. 一些实操心得与避坑建议

先说一个我踩过的坑:一开始我以为这条通路是数字基带产生的,所以在软件里拼命改基带配置,结果什么也没测到。后来才意识到,它完全是射频前端的行为,和基带没关系。所以如果你要试,直接奔着射频寄存器去,别在基带那边浪费时间。

第二个坑是屏蔽。我一开始没在意,觉得低频信号受外部干扰小,结果测出来的数据跳得厉害。后来把模组放进金属盒子里,数据立刻就稳了。低频段虽然外部干扰少,但电源纹波和地线环路的影响很大,屏蔽和滤波一定要做好。

第三个坑是寄存器写保护。ESP32 的射频寄存器默认是锁定的,你必须先解锁才能写入。解锁序列在技术参考手册里有,但藏得很深,我找了好一会儿才找到。如果你写寄存器没反应,先检查是不是没解锁。

最后分享一个小技巧:如果你没有频谱仪,可以用声卡来代替。把天线端口的信号经过一个简单的检波电路,变成音频信号,然后输入声卡,用音频分析软件看频谱。虽然频率范围有限,但测 1MHz 到 10MHz 的信号完全没问题。我用这个方法在笔记本上就能做初步验证,很方便。

这个内容后续还可以这样扩展:一是把不同型号的 ESP32 都测一遍,整理成对照表;二是把接收链路也详细测一下,看看能不能做更复杂的信号处理;三是尝试用这条通路做简单的通信,虽然速率会很低,但作为实验挺有意思的。等我后面有时间了,再慢慢填这些坑。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进