
去年年底整理家里那堆吃灰的开发板翻出一块TEF6686收音机模块和一块ESP32突然冒出个想法能不能把这两个东西拼起来做一台能揣口袋里的便携式DSP收音机折腾了差不多一个月从硬件接线到软件调通再到画外壳、组装调试总算是做出了一个像样的成品。这台机器收台稳、选择性好、声音干净和传统模拟收音机完全是两个时代的体验。今天就把整套方案从头到尾整理一遍包括选型思路、硬件连接、软件逻辑、调试经验和踩过的坑想玩DSP收音机或者想把手头模块利用起来的朋友可以直接照着做。1. 项目定位与整体设计思路拆解1.1 为什么选TEF6686而不是常见收音芯片很多人在做DIY收音机时第一个想到的是Si4735这类芯片它确实便宜、资料多、Arduino社区也成熟。但Si4735的性能上限摆在那里尤其是弱信号下的灵敏度和抗镜像干扰能力和汽车级芯片有明显差距。TEF6686是恩智浦面向车载收音机推出的DSP调谐器内部把射频前端、中频采样、数字解调和RDS解码集成在一颗芯片里FM支持64到108MHzAM支持144到1710kHzLW也能覆盖。实际使用中最直观的感受就是同样一根30cm拉杆天线TEF6686能稳定收到的台Si4735多半已经冒出一片沙沙声。用大白话说传统模拟收音机是“手工灶台”靠一堆分立元件调中频、调带宽DSP收音机则是“数字厨房”射频信号进来后先变成数字信号再用算法去滤波、解调、抑制干扰。TEF6686厉害的地方在于它的ADC位数高、DSP算力足动态范围和选择性都有保障在强台旁边收弱台时优势尤其明显。1.2 为什么主控选ESP32而不是Arduino UNO或STM32既然芯片已经能完成大部分接收和解调工作主控的任务就变成了通过I2C配置芯片、读取状态、处理按键和编码器、驱动显示屏、管理电台列表。这些活儿用Arduino UNO也能凑合但UNO的RAM太小跑RDS字符串缓冲和菜单逻辑比较吃力而且没有浮点运算单元画信号强度条虽然不至于卡死但总觉得不够顺手。ESP32的优势就非常直接双核240MHz、520KB SRAM、4MB以上的FlashWi-Fi和蓝牙都是标配。这意味着除了做一个单纯收音机后续还能加蓝牙音频发射、手机App远程遥控、网络对时等玩法。实际开发中我用的是ESP32 DevKit板配Arduino框架生态成熟网上案例多调试起来非常省心。如果项目追求极致体积也可以换成ESP32-Mini或ESP32-S3模组但接线难度会高一些。1.3 整体架构ESP32 TEF6686 显示 音频放大整套系统的数据流并不复杂。天线接收到射频信号后进入TEF6686模块芯片完成调谐、混频、数字化解调输出立体声模拟音频到功放功放驱动耳机或小喇叭。ESP32在这条链路里扮演“大脑”角色通过I2C总线向TEF6686发送频率设置、搜索命令、带宽调节等指令同时读取信号强度、RDS信息另外一边ESP32读取旋转编码器的转动来调台把频率、电台名、信号强度条显示在OLED屏上。电源部分采用单节18650锂电池供电经过充电管理模块和稳压电路分别给ESP32、TEF6686模块、OLED和功放供电。这里有个设计关键数字电路和模拟音频电路的地线必须仔细处理否则扬声器里会出现持续的“嘶嘶”底噪。后面我会专门讲这个。2. 硬件搭建与电路要点2.1 元器件清单与选型建议先列一份我实际使用的清单供参考主控ESP32 DevKitC V4板载CP2102调试方便收音模块TEF6686 HN模块常见于海鲜市场和海外代购带I2C接口和音频输出显示屏0.96寸SSD1306 OLEDI2C接口128x64分辨率旋转编码器EC11带按键开关用于调台和菜单操作音频功放PAM8403数字功放板驱动8欧3W小喇叭如果只做耳机版可以换TDA1308耳放模块天线FM用30cm拉杆天线或耳机线AM用磁棒天线电池与电源18650电池、TP4056充电模块、MT3608升压模块、AMS1117-3.3稳压模块外壳3D打印尺寸约100x60x25mm选元件时有几个细节要注意。TEF6686模块有很多版本接口定义不统一买的时候一定要看商品页面提供的接线图确认模块上的丝印和说明书不要想当然。PAM8403虽然便宜但供电电压范围和声音底噪不如专门针对耳机优化的耳放芯片如果追求音质建议直接上TPA6130A2这类耳机功放。OLED和编码器没什么坑选择常见型号即可。2.2 接线方案与电源设计我整理了一份标准的接线表老朋友可以直接抄新手照着接也不会出错。注意ESP32的I2C默认引脚是GPIO21SDA和GPIO22SCLTEF6686模块和OLED可以共用同一组I2C总线只要地址不冲突就行。功能ESP32引脚外部设备引脚I2C SDAGPIO21TEF6686 SDAOLED SDAI2C SCLGPIO22TEF6686 SCLOLED SCL编码器A相GPIO32EC11 A编码器B相GPIO33EC11 B编码器按键GPIO34EC11 SW音频左声道-TEF6686 L-OUT - 功放L-IN音频右声道-TEF6686 R-OUT - 功放R-IN功放输出-喇叭/耳机电源部分我最终采用“电池直供升压再分级稳压”的方案。电池正极先接到TP4056模块实现对18650的充电保护TP4056的OUT端进入MT3608升压到5V然后兵分两路一路给ESP32 DevKit的5V输入脚另一路通过AMS1117-3.3降到3.3V给TEF6686模块的逻辑部分、OLED和编码器使用。这里必须强调一个很多人容易忽略的点功放的电源和数字模块的电源不能直接并在一起。PAM8403工作时电流波动大如果和TEF6686共用一根电源线功放抽动电流造成的电压纹波会直接污染收音芯片表现出来就是声音里带着“嗡嗡”的电流声。我后来在功放电源入口串了一颗100µH电感和一个470µF电解电容做LC滤波底噪立刻小了很多。2.3 天线与音频输出的处理FM天线可以直接焊在TEF6686模块的ANT焊盘上。我的做法是在外壳侧面装一个SMA插座配合拉杆天线方便更换不同长度的天线。测试下来30cm拉杆天线在城市里能收到20个以上的FM台50cm天线在高楼层能收到40个左右效果还是很明显的。如果只用耳机线做天线记得把耳机线的一条地线接到天线输入否则信号会非常弱。AM天线则完全不同TEF6686需要接磁棒天线或大环天线。磁棒线圈的匝数和电感量要按照芯片手册推荐的匹配网络来设计我的第一版直接用普通中波磁棒线圈接上去信号非常差。后来按模块卖家提供的数据重新绕了线圈才恢复正常。这一点强烈建议购买模块时一并问清楚天线匹配方案。音频输出方面TEF6686模块的音频输出引脚输出的是模拟立体声信号可以直接接耳机功放。如果耳机和喇叭两种方式都想要可以在功放输出端用一个3.5mm耳机插座自带切换开关的结构插入耳机时自动断开喇叭。这个小细节能省不少事不用手动切换。3. 软件实现与核心代码逻辑3.1 开发环境与库的选择软件部分我首选Arduino框架不是因为ESP-IDF不好而是这个项目需要快速验证硬件Arduino的库生态能省掉大量底层时间。开发环境用VS Code加PlatformIO插件比Arduino IDE更好用至少代码补全和串口监视器体验提升了一个档次。PlatformIO里搜索TEF6686相关库时能找到社区维护的封装库比如GitHub上常见的TEF6686_ESP32项目已经把大部分命令封装成了现成函数直接调setFrequency、seekUp这类方法就行。不过我不建议完全什么都不看就调用。至少要打开库的源文件扫一眼明白每个命令大概做了什么后面排查问题会快很多。如果实在找不到合适的库也可以根据NXP的TEF6686命令表自己写I2C发送函数工作量不大但需要仔细读协议。3.2 TEF6686 I2C通信与关键寄存器TEF6686不像普通传感器那样简简单单读几个寄存器就行它的控制方式是“命令-响应”模式。主控通过I2C向芯片写入一串包含命令码和参数的数据芯片执行后再返回状态数据。I2C地址通常是0x60不同模块可能不一样第一次焊接完先跑一个I2C扫描程序确认地址能省掉很多后续排查时间。下面这段是Arduino环境下的I2C扫描代码直接烧录后打开串口监视器就能看到总线上挂载的设备和地址。#include Wire.h void setup() { Wire.begin(); Serial.begin(115200); Serial.println(Start I2C scan...); } void loop() { byte error, address; int nDevices 0; for (address 1; address 127; address) { Wire.beginTransmission(address); error Wire.endTransmission(); if (error 0) { Serial.print(Found device at 0x); if (address 16) Serial.print(0); Serial.println(address, HEX); nDevices; } } if (nDevices 0) Serial.println(No devices found); delay(2000); }扫描成功后再跑一个库自带的示例程序设置一个已知电台频率比如调到一个本地强台看看能不能听到声音。如果这一步通了说明I2C通路和TEF6686的基本调谐功能没问题后面再往UI方向加功能就顺了。3.3 电台搜索、RDS解码与UI逻辑电台搜索的逻辑其实可以做成“暴力扫描”从当前频率或最低频率开始按固定步进向上搜索每次设置频率后等待几百毫秒再读取TEF6686返回的信号强度值。如果强度高于阈值就认为找到一个台记录下来并继续搜索。这个方案简单直接唯一的代价是搜索速度偏慢但便携收音机本来就不需要秒级搜台。RDS解码是TEF6686的强大功能之一芯片硬件上已经解调好RDS数据主控只需要通过I2C读取缓冲区提取电台名PS和广播文本RT。实际效果是OLED屏幕能显示当前电台的呼号比如听到某个立体声广播时会显示对应字符串。国内FM台的RDS普及率不高但至少能显示“RDS”标记调试起来也很有趣。UI层我用简洁思路主界面显示频率、信号强度条、FM/AM频段标识、立体声状态、RDS信息短按编码器进入菜单旋转切换菜单项再短按确认。编码器需要软件消抖可以在中断里判断A相和B相的相位差来确认旋转方向同时用按键消抖状态机处理短按和长按的区别。4. 实操过程记录与参数调试4.1 从零到出声的完整流程如果你准备复刻这个项目我建议按下面的顺序一步步来每一步都验证通过后再进入下一步这样出问题时能快速锁定范围。第一步面包板搭接最小系统。只接ESP32和TEF6686模块供电用USB线给ESP32供电从板子的3.3V引出来给TEF6686模块。跑I2C扫描程序确认总线上能看到0x60设备。第二步跑通搜台和发声。接好TEF6686的音频输出到耳机功放用库的示例代码设置一个本地强台耳机里能听到声音就说明基本通路已经打通。这一步如果没声音优先检查天线和音频线焊接其次检查I2C命令是否正确。第三步加入OLED显示和编码器。这个阶段编程量最大但底层的调谐和音频已经没问题了剩下的只是UI逻辑。我习惯先把频率显示和转动编码器改频率做成最简单的版本跑通后再加菜单和RDS。第四步移入外壳处理电源。把面包板上的元件转移到外壳内用热熔胶固定模块和电池。这里要特别注意前面说的电源滤波问题否则装壳之后底噪可能比面包板时代还要大。第五步整体参数打磨。反复测量天线长度、功放音量、供电电压把最终参数固定下来。4.2 频段、去加重、灵敏度等参数调试参数调试是决定整台机器“气质”的关键。我在这里折腾最多也最有心得。第一个参数是FM去加重。不同国家和地区的调频广播去加重时间常数不同美洲通常用75µs欧洲和中国大部分地区用50µs。TEF6686可以通过命令设置去加重时间常数如果设错了高音会变得毛躁或者发闷。我一开始用库的默认设置声音总觉得高频刺耳后来改成50µs才正常。第二个参数是AGC自动增益控制。强信号和弱信号之间的音量差异调节好了收音机才耐听。TEF6686的AGC非常灵敏但如果AGC响应太快听本地强台时能感受到“强弱交替”的呼吸感适合把攻击时间和释放时间调慢一些换来更平稳的听感。第三个参数是AM带宽。中波广播的带宽选择要平衡音质和噪声带宽越宽音质越好但噪声越大带宽越窄保真度下降但弱信号下更清晰。我一般听语音类节目时选4.5kHz左右听音乐时选6kHz以上这个参数可以在菜单里做成可调项不同场景切换更方便。第四个参数是搜台静音。很多DSP芯片在搜索频率时会把音频输出静音避免扫台过程中的“沙沙”声。不过如果静音过度搜台过程会显得“卡顿”我习惯把静音时间设短扫台过程中还能听到短暂的白噪声像极了老收音机的扫描感。5. 常见问题与排查技巧实录5.1 I2C不通、收不到台、底噪大等场景这个项目里我遇到的绝大多数坑都集中在硬件和参数设置上有几类问题非常典型这里单独分享。I2C扫描不到TEF6686模块时先量模块供电TEF6686的逻辑部分需要3.3V如果模块上有板载稳压则可以直接接5V但不同模块不一样接错电压轻则不工作重则烧芯片。我有一块模块就是买回来直接接5V到逻辑引脚结果冒了烟。另外I2C上拉电阻也很关键ESP32内部带有上拉但长导线或模块负载较重时可能不够外部加两颗4.7kΩ电阻到3.3V能显著提高稳定性。收不到台或收台很少首先要排除天线问题。FM天线最好用拉杆天线随手焊一根短线是收不了几个台的。其次是检查频率范围和频段设置是否正确有些库默认把FM范围限制在64到108MHz如果你的区域超出这个范围低端或高端电台就搜不到。AM天线更是大头磁棒线圈的电感量稍有偏差灵敏度就会掉一大截。底噪大的问题我遇到过两种情况一种是电噪声表现为持续的“嘶嘶”声和调台无关这种多半是电源或地线问题另一种是音频自激表现为“啸叫”通常是功放增益过大或输出地和输入地靠太近。解决电噪声可以从电源LC滤波和单点接地入手解决自激则适当降低功放增益并在功放电源引脚就近放一个100nF电容。5.2 问题排查速查表为了方便排查我把常见问题整理成了一张速查表遇到问题直接对照看。现象可能原因解决办法I2C扫描不到模块供电错误、接线反了、地址不对先量供电电压再核对丝印扫描程序改成全地址扫描能设置频率但没有声音音频输出接错、静音开关未打开、功放无供电确认L-OUT/R-OUT接对检查硬静音引脚电平量功放供电收台少且信号弱天线太短、天线匹配不对、频段设置错误换拉杆天线检查FM天线焊接核对该地区频率范围底噪滋滋响地线环路、电源纹波大、音频线离数字线太近单点接地功放电源加LC滤波音频线走线远离I2C线编码器调台乱跳按键抖动、GPIO中断配置错误硬件加100nF电容消抖软件增加状态机消抖OLED花屏或黑屏I2C速率太高、OLED地址冲突、供电不稳定把I2C速率降到100kHz换不同地址OLED电源加电容搜台总是停不准静音阈值太低、步进不匹配调高信号强度阈值确认搜索步进符合区域制式5.3 独家调试技巧最后分享几个常规文档里不会写、但实测非常管用的技巧。调试时没有示波器没关系学会用“替换法”和“听觉法”判断故障区间。比如收不到台先直接手动设置一个已知强台频率如果还没有声音问题就缩小到天线、音频输出或I2C通信如果有了声音但搜台扫不到再往下查搜索参数。这样一步步收窄范围比拍脑袋换硬件高效得多。另一个技巧是“电源分区测试”。整机装完后底噪变大可以用飞线把功放电源从主电源上断开外接一个干净的5V电源如果底噪消失就确定问题出在电源污染上再针对性加滤波。还有一点TEF6686的命令手册非常长很多参数在库文件里虽然有默认值但未必适合你所在的地区和天线配置。遇到细节问题时不要害怕直接翻手册把命令字节一个个弄明白这个项目做下来你对数字收音芯片的理解会远超只会抄代码的人。最后再分享一点心得如果让我重新做一遍我会在外壳设计上多花点心思。第一版外壳把OLED嵌在前面板、编码器放在侧面看似合理但实际握持时手指总挡住天线接头信号时好时坏。后来我把天线插座挪到机器顶部编码器挪到前面板右下角握持和操作才舒服很多。DIY项目就是这样功能跑通只是第一步能不能日常用、用得顺手才是真正决定成败的地方。这个项目后续还可以扩展蓝牙音频发射、网络校时、手机App遥控、自动扫描电台列表等功能折腾空间很大。希望这篇全攻略能帮你把想法变成现实也期待看到你的作品。