1. 项目概述:基于Si4731与PIC18F87K22的DIY收音机开发
最近在整理工作室时翻出一台老式晶体管收音机,这让我想起学生时代用面包板搭接收音电路的场景。如今虽然手机能听万物,但亲手制作一台能接收FM/AM信号的数字调谐收音机,依然是电子爱好者验证硬件设计能力的经典项目。这次我们将使用Silicon Labs的Si4731数字接收芯片与Microchip的PIC18F87K22单片机,构建一个可编程控制的收音机系统。
Si4731作为高度集成的广播调谐器芯片,支持64-108MHz的FM频段和520-1710kHz的AM频段,通过I2C接口即可实现频道选择、音量控制等所有功能。而PIC18F87K22这款8位单片机凭借其丰富的外设(特别是硬件I2C模块)和充足的IO资源,成为驱动Si4731的理想选择。整个项目涉及射频电路设计、单片机编程、人机交互界面开发等多个电子工程核心技能点,完成后的设备不仅能收听广播,还可扩展录音、频谱显示等进阶功能。
2. 硬件设计详解
2.1 核心器件选型分析
选择Si4731而非更新的Si4735,主要基于三点考虑:首先作为基础型号,Si4731的文档资料更为丰富,社区支持更好;其次它保留了关键的RDS(Radio Data System)功能,可以显示电台名称等信息;最重要的是其典型应用电路已经过大量项目验证,成功率高。实测在3V供电下,Si4731的接收灵敏度可达2μV(FM模式)和50μV(AM模式),完全满足日常使用需求。
PIC18F87K22的竞争优势体现在三个方面:内置的I2C主控模块能稳定运行在400kHz高速模式;多达80KB的Flash存储空间可容纳复杂菜单逻辑;8MHz内部振荡器省去外部晶振,简化PCB布局。其44引脚TQFP封装在保证IO数量的同时,也适合手工焊接。
2.2 关键电路设计要点
射频输入部分需要特别注意阻抗匹配。FM天线输入端建议采用75Ω同轴接口,通过一个1:4巴伦变压器转换为芯片所需的单端输入。具体电路为:SMA接头→BLF15-03巴伦→10pF隔直电容→Si4731的FMI引脚。AM模式则直接在AMI引脚连接2m左右的导线作为天线。
电源滤波是另一个设计重点。实验表明,在Si4731的3.3V供电线上并联100nF陶瓷电容与10μF钽电容,能有效抑制数字噪声对接收灵敏度的干扰。PCB布局时应确保这两个电容尽可能靠近芯片电源引脚,地平面需完整不间断。
重要提示:Si4731的复位引脚(RESET)必须通过10kΩ电阻上拉到VDD,否则芯片无法正常启动。这是新手最容易忽略的设计细节。
3. 软件开发实战
3.1 开发环境搭建
使用MPLAB X IDE v5.50作为主开发环境,配合XC8 v2.36编译器。新建工程时需注意两点:一是将芯片型号严格选择为PIC18F87K22;二是在Linker选项中启用"Extended mode"以支持大容量存储。为方便调试,建议安装PICKit3/4编程器驱动,并启用ICD调试功能。
建立基本的I2C通信框架是首要任务。初始化代码如下:
void I2C_Init() { SSP1STAT = 0x80; // Slew rate disabled SSP1CON1 = 0x28; // I2C Master mode, clock = FOSC/(4*(SSP1ADD+1)) SSP1ADD = 39; // 设置I2C时钟为100kHz (8MHz晶振时) TRISC3 = 1; // SCL引脚设为输入 TRISC4 = 1; // SDA引脚设为输入 }3.2 Si4731驱动开发
芯片初始化流程包含关键步骤:
- 硬件复位后延迟100ms
- 发送Power Up命令(0x01)设置工作模式
- 配置波段参数(FM模式下建议去加重设置为50μs)
- 设置音量(初始值建议12/63)
读取RDS数据的典型代码结构:
uint8_t rdsBuffer[8]; void GetRDS() { I2C_Start(); I2C_Write(0x22); // Si4731写地址 I2C_Write(0x24); // RDS状态命令 I2C_Start(); I2C_Write(0x23); // Si4731读地址 for(uint8_t i=0; i<7; i++) rdsBuffer[i] = I2C_Read(1); // 带ACK的读取 rdsBuffer[7] = I2C_Read(0); // 最后字节无ACK I2C_Stop(); }4. 系统集成与调试
4.1 硬件组装要点
焊接顺序建议:先贴片元件(电阻电容),再芯片,最后接插件。使用热风枪焊接Si4731时,温度控制在300°C以下,每个引脚加热时间不超过3秒。实测发现,在芯片底部涂抹少量焊膏能显著提高焊接成功率。完成焊接后,务必用放大镜检查是否有桥接,特别是0.5mm间距的Si4731引脚。
初次上电测试流程:
- 仅连接3.3V电源,测量各引脚电压
- 用示波器检查I2C时钟线是否正常
- 通过逻辑分析仪捕获初始化命令序列
- 逐步接入天线和音频输出
4.2 典型问题排查
案例:FM接收时出现间歇性静音 排查过程:
- 用频谱仪观察本振泄漏→正常
- 检查电源纹波→发现3.3V上有200mVpp噪声
- 更换为LDO稳压器后问题依旧
- 最终发现是I2C上拉电阻值过大(原47kΩ改为4.7kΩ后解决)
案例:AM模式灵敏度低 解决方案:
- 确认天线连接正常
- 调整AMI引脚的对地电容(最终选用220pF)
- 在软件中设置合适的RF增益(命令0x40参数设为0x01)
5. 功能扩展与优化
5.1 添加LCD显示界面
选用常见的1602字符LCD时,需注意其3.3V兼容性。推荐通过PCF8574T I2C扩展模块驱动,这样只需4根线即可连接。显示内容可包括:
- 当前频率(如"FM 98.5MHz")
- 信号强度指示条
- RDS电台名称(当接收到时)
- 音量等级图标
优化技巧:建立显示缓冲区,仅在有变化时刷新LCD,可降低50%以上的功耗。实测表明,采用部分刷新策略后,系统待机电流从15mA降至8mA。
5.2 实现频道存储功能
利用PIC18F87K22的EEPROM存储预设频道:
void SaveChannel(uint8_t pos, uint32_t freq) { uint8_t *p = (uint8_t*)&freq; NVMCON1bits.NVMREG = 1; // 选择EEPROM存储区 for(uint8_t i=0; i<4; i++) { NVMDAT = p[i]; // 写入数据字节 NVMADR = pos*4 + i; // 计算EEPROM地址 _asm MOVFF _NVMCMD, 0xCA _endasm // 特殊指令序列 _asm MOVFF _NVMCMD, 0x55 _endasm _asm MOVFF _NVMCMD, 0xAA _endasm NVMCON1bits.WR = 1; // 启动写入 while(NVMCON1bits.WR); } }6. 实测性能与改进方向
在市区环境下的实测数据:
- FM接收:可稳定接收25个电台,最远距离达50km
- 信噪比:65dB(典型值)
- 音频失真度:<0.8%
- 切换频道响应时间:120ms(含RDS解码)
下一步改进计划:
- 增加DSP音效处理(如均衡器)
- 移植FreeRTOS实现多任务管理
- 设计3D打印外壳
- 开发手机APP通过蓝牙控制
这个项目最让我惊喜的是Si4731的RDS解码稳定性——即使在弱信号下,仍能正确解析电台名称。建议有兴趣的读者尝试用旋转编码器替代按键调谐,操作手感会有质的提升。