1. 项目概述:用Si4731和PIC18F46K20打造个性化收音机系统
作为一名电子爱好者,我一直对无线电接收技术充满兴趣。最近在整理工作室时翻出了几片Si4731数字调频接收芯片和PIC18F46K20单片机,决定将它们组合起来制作一个可编程的收音机系统。这个项目的核心价值在于:通过低成本硬件实现传统收音机的数字化控制,同时保留模拟调谐的手感体验。
Si4731是Silicon Labs推出的一款高性能数字调频/调幅接收芯片,支持64-108MHz的宽频段接收。相比传统模拟芯片,它的优势在于:
- 数字信号处理(DSP)技术带来更好的抗干扰能力
- 可编程的接收带宽(50kHz-400kHz)
- 内置RDS(Radio Data System)解码功能
- I²C控制接口简化系统设计
PIC18F46K20则是Microchip的8位单片机,在这个项目中扮演"大脑"角色:
- 44引脚TQFP封装提供充足IO资源
- 内置I²C主控接口可直接驱动Si4731
- 64KB闪存空间可存储预设频道
- 丰富的定时器资源支持旋钮编码器解码
2. 硬件设计与关键电路实现
2.1 核心电路连接方案
整个系统的硬件架构可分为三个主要部分:
射频前端电路:
- Si4731的ANT引脚接50Ω偶极天线
- 采用LC匹配网络优化接收灵敏度
- 电源端并联10μF钽电容和100nF陶瓷电容
控制单元电路:
- PIC18F46K20通过I²C(SCL/SDA)与Si4731通信
- 旋转编码器接PORTB用于调谐
- 128x64 OLED显示屏显示频率和信号强度
音频输出电路:
- Si4731的LINE_OUT接10kΩ音量电位器
- LM386构成音频功率放大器
- 8Ω/1W扬声器作为负载
关键提示:Si4731对电源噪声敏感,建议在PCB布局时将去耦电容尽量靠近芯片电源引脚,地平面要完整。
2.2 特殊元件选型考量
在元件选择上,有几个需要特别注意的点:
天线匹配电路:
- 使用7x0.8mm空心线圈(约0.3μH)与22pF可变电容组成谐振电路
- 通过网分仪调整使谐振点在98MHz附近
- 实际测试表明,这种配置在城市环境可接收15km内的电台
旋转编码器:
- 选用EC11系列机械编码器
- 内置20脉冲/转的物理结构
- 通过单片机定时器捕获模式解码
- 需要添加10nF电容硬件消抖
显示模块:
- SSD1306驱动的0.96寸OLED
- 采用SPI接口节省IO资源
- 自定义UI显示频率、信号强度和RDS信息
3. 固件开发与核心算法
3.1 Si4731驱动实现
PIC单片机通过I²C控制Si4731需要遵循特定的通信协议。以下是关键操作流程:
- 初始化序列:
void Si4731_Init() { I2C_Start(); I2C_Write(0x22); // Si4731写地址 I2C_Write(0x01); // POWER_UP命令 I2C_Write(0x50); // FM接收模式 I2C_Stop(); __delay_ms(500); // 等待芯片稳定 }- 频率设置:
void SetFrequency(uint16_t freq) { uint8_t freqH = (freq >> 8) & 0xFF; uint8_t freqL = freq & 0xFF; I2C_Start(); I2C_Write(0x22); I2C_Write(0x20); // TUNE_FREQ命令 I2C_Write(0x00); // 保留位 I2C_Write(freqH); I2C_Write(freqL); I2C_Stop(); }- 信号质量读取:
uint8_t GetRSSI() { I2C_Start(); I2C_Write(0x22); I2C_Write(0x23); // GET_INT_STATUS命令 I2C_Stop(); I2C_Start(); I2C_Write(0x23); // 读地址 uint8_t rssi = I2C_Read(0); I2C_Stop(); return rssi; }3.2 旋钮解码算法
机械编码器的处理需要特别注意消抖。我的实现方案是:
- 配置Timer0产生5ms中断
- 在中断服务程序中采样AB相状态
- 使用状态机识别有效旋转方向
// 编码器状态定义 #define ENC_STATE_00 0 #define ENC_STATE_01 1 #define ENC_STATE_11 2 #define ENC_STATE_10 3 volatile uint8_t encState = ENC_STATE_00; void __interrupt() ISR() { static uint8_t lastAB = 0; uint8_t currentAB = (PORTBbits.RB4 << 1) | PORTBbits.RB5; if(lastAB != currentAB) { // 状态转移处理 if((lastAB == 0x00 && currentAB == 0x01) || (lastAB == 0x01 && currentAB == 0x11) || (lastAB == 0x11 && currentAB == 0x10) || (lastAB == 0x10 && currentAB == 0x00)) { // 顺时针旋转 freq += 50; // 50kHz步进 } else { // 逆时针旋转 freq -= 50; } lastAB = currentAB; } }4. 系统优化与实测效果
4.1 接收灵敏度提升技巧
经过反复测试,我总结了几个提升FM接收效果的方法:
天线优化:
- 使用1/4波长(约75cm)导线作为天线
- 通过巴伦匹配阻抗
- 远离电脑等数字设备放置
软件滤波:
// 移动平均滤波RSSI值 #define FILTER_SIZE 5 uint8_t rssiFilter[FILTER_SIZE]; uint8_t filterIndex = 0; uint8_t FilterRSSI(uint8_t newVal) { rssiFilter[filterIndex] = newVal; filterIndex = (filterIndex + 1) % FILTER_SIZE; uint16_t sum = 0; for(uint8_t i=0; i<FILTER_SIZE; i++) { sum += rssiFilter[i]; } return sum / FILTER_SIZE; }- 频偏校准:
- 接收已知频率的标准信号
- 测量实际接收频率偏差
- 在代码中添加补偿值
4.2 实际使用体验
完成后的系统具有以下特点:
- 频率覆盖87.5-108MHz全波段
- 50kHz/100kHz两种步进模式可切换
- 可存储10个预设频道
- RDS信息显示电台名称和节目类型
- 信噪比优于传统模拟收音机
实测在城市环境中:
- 可稳定接收20个以上FM电台
- 切换频道响应时间<200ms
- 静态电流约45mA(含显示背光)
经验之谈:调试时发现,Si4731的I²C时序要求比较严格,当单片机主频超过16MHz时,需要适当插入NOP指令来满足时序要求。这是数据手册中没有明确说明的细节。
5. 扩展功能与改进方向
目前的系统已经具备基本功能,但还有不少可以提升的空间:
自动搜台增强:
- 实现全频段扫描
- 根据信号强度自动排序
- 跳过无信号频点
音频处理扩展:
- 添加均衡器调节
- 支持蓝牙音频转发
- 录音功能实现
低功耗优化:
- 采用锂电池供电
- 增加睡眠模式
- 光感自动调节屏幕亮度
外壳设计:
- 3D打印复古收音机造型
- 旋钮阻尼调校
- 防滑底座设计
这个项目最让我满意的是,用不到100元的成本实现了商业收音机数百元产品的核心功能。特别是在理解Si4731的RDS解码功能后,可以显示电台发送的实时信息,这在交通广播等场景非常实用。