
RDA5807FP升级版
简介
RDA5807FP收音机升级版
简介:RDA5807FP收音机升级版开源协议
:GPL 3.0
描述

之前开源过使用RDA5807FP制作的简易收音机,就是不需要主控,只用它加上一些外围电路就搭建起来的收音机。
今天来详细了解一下它,并且将之前的升级一下,至少是加入主控芯片,然后再加个显示屏之类的。

在手册第一页我们关注几点。
就是它的电压范围是2.7V~3.3V,一般给个3.3V,刚好也是大多数单片机的供电电压。
另外我们需要给它晶振,支持很多种,但是一般我们给个32.768KHz的晶振就可以了,这也是它寄存器里的默认配置。
最后就是它可以接收到的频率是50~108MHz,我国的广播频率范围是被包含在里面的,可以正常使用。我这边能搜到的台都是在70~90MHz的。
首页没有提到的一个重要的点是它支持I2C控制。
另外它没有I2C控制其实也是可以的,但是它的手册里没有体现出来,我之前还是通过热心网友才知道的。

可以先来看看它的引脚,SOP16封装,还是比较好焊接的。
其中有五个GND,还有个RF GND,不过我们直接把它们都接到GND就行,手册里给出的原理图也是这样的。
或许最好是要单点接地什么的?我对这方面不是很了解。
然后它甚至还有三个GPIO可以用,反正我是没用到,给它悬空就行,不过你具体要不要用可以看后面介绍寄存器的时候再做决定。

外围电路不复杂,直接抄手册里的就行。
顺带一提,F1和F2是磁珠(以防小白小伙伴没看出来)。
实测C7和ESD不加也没事,因为我做的时候忘记了,但是你们记得加上,我这收音信号不好或许就跟C7有关系。
我画出来差不多是下面这样。

我用的立创EDA,不过立创商城里没有RDA5807FP。
要使用的话可以自己画封装,或者像下图这样用别人画好的。

淘宝买的话,一个芯片差不多是一块钱左右。
关于RDA5807FP的外围电路就先说这么多,反正跟着手册画就行。
接下来重点要看寄存器,这是我们使用I2C去控制它的关键。
它支持两种模式的I2C,一种是连续模式,另一种就是标准I2C。
连续模式我们不用管,我觉得用起来很麻烦,所以我们只看标准I2C就行。

标准I2C就不用我多介绍了吧。
它的从机地址是0010001,写地址就是0010 0010(0x22),读地址就是0010 0011(0x23)
它有五种工作模式。

不过我不算讲,反正后面我们只要能用就行了,记那么多概念没用。
我们按照手册里的步骤来。

第一步就是复位,复位完再上电。
复位就是把0x0002写到02H寄存器里,上电操作就是把0xC001写到02H寄存器里。
这一步涉及到的寄存器就是02H,所以我们先来看02H。
每个寄存器都有俩字节。

整个截图有点大,我们先看高八位。
Bit15是音频高阻,可以看做是使能位,0就是高阻,也就是没声音,1就是正常,有声音。
Bit14是静音,0就是静音,1就是正常。
Bit13是单双声道,默认0双通道,如果你想要单声道(万一呢),就改为1。
Bit12是低音增强,1开启,不过反正我是没听出什么区别。
Bit11手册里标黄底了,说明挺重要,但是可惜的是我没看懂啥意思,反正我们就按照它默认的0别改就行。
Bit10同上。
Bit9和Bit8用来自动搜台的,一个是启动搜台,一个是决定搜台方向,这个后面代码部分细聊。


接下来是低八位。
Bit7也是跟搜台相关的,原谅我英语不好,没理解啥意思,反正看不懂的咱就按照默认值处理。
Bit6~Bit4三位用来选择晶振频率,默认是000也就是32.768KHz,如果用的别的晶振就要修改。
Bit3启用RDS,那么这个RDS是什么呢,我不懂,大概查了一下RDS 即 Radio Data System(无线数据广播系统),貌似是没啥用,启不启用都行,我就不用了。
Bit2启用新的调解方法,提升1dB的灵敏度,1db有多少不太清楚,应该不是很多吧。。。也是启不启用都行,我就用了。
Bit1和Bit0比较关键,一个是复位,一个是启动。
所以我们复位的时候是往02H写入0002,就是单单把bit1给置1,也就是软件复位。
然后等待50ms等它复位完再写入0xC1启动。
0xC001就是1100 0000 0000 0001。
结合着寄存器的含义我们就知道手册让我们写入0xC001是做什么了。
就是使能芯片,取消音频高阻,解除静音。
如果要改配置的话,我们再修改写入的值就是了,比如说我要用新的调解方法,哪怕就1db我也想用,那么我写入的就是0xC005。
写完之后我们要等待600ms。

是从手册里的伪代码里看到的。
保险起见可以多延时一会儿。
接下来我会把一些步骤的代码贴出来,我用的是STC32,要用别的芯片也是可以的,反正大概看个意思就行,show me the code是吧。
void Z_RDA5807FP_Init(void){
u8 temp[2] = {0};
// 复位
temp[0] = 0x00; temp[1]=0x02;
I2C_WriteNbyte(RDA5807FP_ADDR, 0x02, temp, 2);
delay_ms(50);
// 上电
temp[0] = 0xC0; temp[1] = 0x05;
I2C_WriteNbyte(RDA5807FP_ADDR, 0x02, temp, 2);
delay_ms(600);
// 修改频段为76~108MHZ
I2C_ReadNbyte(RDA5807FP_ADDR, 0x03, temp, 2);
temp[1] |= 0x08;
I2C_WriteNbyte(RDA5807FP_ADDR, 0x03, temp, 2);
}
下一步为了确保芯片没问题,可以读取一下芯片ID。

00H这个寄存器,高八位就是芯片ID了,固定是0x58,如果读出来不是的话,你就要好好反思一下自己是哪里出了问题了。
只读一个字节就行,读两个也可以,我读出来是0x58 04。
u8 Z_RDA5807FP_GetID(void){
u8 ID[2] = {0};
I2C_ReadNbyte(RDA5807FP_ADDR, 0x00, ID, 2);
printf("ID is %#X %#X\r\n", ID[0], ID[1]); // 0x58 0x04
return ID[0];
}
ID读出来没问题的话就等于是可以让RDS5807FP工作了,作为一个收音机,它最重要的就是收音嘛,所以我们可以来看看如何搜台。
先看03H这个寄存器。

高十位,从bit6到bit15,这个值乘上间距再加上基数,就是收音的频率。
间距是根据bit0和bit1去决定的,比如说默认是00,那么间距就是100kHz。
然后基数我们就看b(这里打断一下,至于为什么打断看下图,有点无语)it2和bit3,比如说默认还是00,那么接收的频率范围就是87~108MHz,基数就是这个87MHz。

所以如果我其他配置都是默认的,然后bit6~bit15写入的数是100。
那么就是设置收音的频率为100 * 100KHz + 87MHz,也就是97MHz。
Bit5没用。
Bit4开启调谐。
如果我们是自动搜台的话,那么就不需要管bit4。
如果我们是指定频道的话,就需要在指定的时候把bit4置1。
指定频道就是通过上面的公式写入bit6~bit15来指定频率,然后再把bit4置1开始调谐。
那我们设置完频率之后,我们应该如何得知设置完了,而且当前的频率是个广播台呢?
这就要看0AH和0BH俩寄存器了。
这俩寄存器都是专门存放标志位供我们查询的寄存器。


Bit15是RDS准备就绪标志位,开启RDS在前面02H的bit3。
Bit14是搜索或者调谐完成标志位,如果我们是自动搜台,那就是搜索,如果是自定义频率,那就是调谐。
我们就要看这一位是否置1来判断搜台结束没有。
Bit13是搜台失败的标志位,如果它被置1了,就表示搜台失败。
Bit12是RDS同步标志位。
跟RDS直接相关的都标黄底了,表示还蛮重要的,但是我其实不是很懂RDS是干嘛的,所以我压根没用它,因此跟RDS有关的我都忽略掉了。
Bit11我也没看懂啥意思,跟RDS有关,不管它了。
Bit10是立体声标志位,一般我们没去动它就是双声道。
Bit9~bit0跟03H寄存器的bit15~bit6差不多,都是表示频率,不过03H的是设置频率,而0AH的是读取频率。
读取当前频段的代码差不多是下面这样的。
// 获取当前频段
double Z_RDA5807FP_GetChannel(void){
u8 temp[2];
double channel = 0;
I2C_ReadNbyte(RDA5807FP_ADDR, 0x0A, temp, 2);
channel = (0x1F & ((temp[0] << 8) | temp[1])) * 0.1 + (spaceFlag == 0 ? 76 : 87);
printf("0x0A is %#X %#X, channel is %f\r\n", temp[0], temp[1], channel);
return channel;
}
不过我多加了个spaceFlag,因为默认频率范围是87~108MHz,我修改为了76~108MHZ,但是我转念一想,这个范围会不会太大了,万一写死的话要改岂不是很麻烦。
然后刚好我画的板子上有四个按键,刚好多出一个不懂干嘛用,就拿来修改频率范围算了,所以就有了这个spaceFlag来决定基数频率是多少。
如果就用一种范围的小伙伴可以直接把那部分写死。
切换频率范围的函数如下
// 切换频率范围
void Z_RDA5807FP_ChangeSpace(void){
u8 temp[2] = {0};
I2C_ReadNbyte(RDA5807FP_ADDR, 0x03, temp, 2);
temp[1] &= 0xF0;
if(spaceFlag == 0){ // 将频段修改为87~108M
spaceFlag = 1;
}else{ // 将频段修改为76~108M
temp[1] |= 0x08;
spaceFlag = 0;
}
I2C_WriteNbyte(RDA5807FP_ADDR, 0x03, temp, 2);
printf("0x03 is %#X %#X\r\n", temp[0], temp[1]);
}
计算公式用的是同一种。
看完0AH我们就知道如何判断搜台结束了没有以及搜台成功了没有。
I2C_ReadNbyte(RDA5807FP_ADDR, 0x0A, temp, 2);
if((temp[0] & 0x40) && !(temp[0] & 0x20)){
printf("find channel success\r\n");
return 1;
}
靠的就是bit14和bit13两位。
接下来看看0BH。


Bit15~bit9是信号强度。
Bit8来表示当前的频率是不是一个频道。
Bit7是FM READY???英文不太好,或许跟初始化相关,表示初始化完成没有。
不过我是参照手册里的来,直接延时600ms然后默认你初始化完成。
Bit6和bit5没用。
Bit4~bit0跟0CH、0DH、0EH、0FH这几个寄存器相关,而这几个寄存器跟RDS相关,所以我们就不看了,包括后面几个寄存器。
其实0BH基本不用怎么看,咱就看个信号强度,不过我们读取到的信号强度是6位的原始数据,看样子好像还要做什么对数处理,具体我不是很懂,所以没用。
还有就是bit8来判断当前频率是不是一个频道。
我是用的自动搜台,所以搜出来的肯定是个频道,因此这一位我也不看。
说到自动搜台那么我们就需要回顾一下02H了。

靠bit9和bit8来开启自动搜台以及搜台方向。
不过我实测的结果是貌似搜台方向不是很管用,有时候我选择向上搜台,它反而搜出来的频道的频率比之前的更低。
也有可能是我信号不好,再往上就没频道了也说不定。
// 向上搜台
u8 Z_RDA5807FP_AddChannel(void){
u8 temp[2] = {0};
u8 i = 0;
I2C_ReadNbyte(RDA5807FP_ADDR, 0x02, temp, 2);
temp[0] = (temp[0] & 0xFC) | 0x03;
I2C_WriteNbyte(RDA5807FP_ADDR, 0x02, temp, 2);
for(i = 0; i < 100; ++i){
delay_ms(200);
I2C_ReadNbyte(RDA5807FP_ADDR, 0x0A, temp, 2);
if((temp[0] & 0x40) && !(temp[0] & 0x20)){
printf("find channel success\r\n");
return 1;
}
}
printf("find channel fail!\r\n");
return 0;
}
另外需要提的就是我们给它设置的步距(03H的bit1和bit0)越大,搜台越快,但是也不能太大,否则可能会遗漏一些频道。
一般来说我们按照默认的100KHz就行。
上面的内容就足够我们去做一个收音机了,事实上我已经把核心代码都贴出来了。
不过接下来我们接着看看其他寄存器,因为我们还漏了一些内容,比如说那三个被我悬空的GPIO口,我是没打算用,但万一你们想用呢?
按照顺序来看看04H。

Bit15跟RDS相关不看。
Bit14是来设置GPIO2的中断的,设置为1就是使能中断,当搜台结束之后,GPIO2会发一个低电平脉冲,我们可以把它接到单片机上来接收。
这样就不用通过读取0AH的bit14来判断是否搜台结束。
不过我没用。

Bit13和bit12是RDS相关的不看。
Bit11设置去重时间,听说是美国广播设置为0,欧洲广播设置为1,这样能提高音频质量。咱中国我就不清楚了,按照默认的来吧,应该差别不是很大。
Bit10为保留位,固定为1。
Bit9软键静音使能位,没用过,不懂效果怎么样,反正给它的音量设置为0之后还是有声音出来。
Bit7也是保留位。
Bit6使能I2S,如果使能了I2S,那么三个GPIO口都会变成I2S的线。

使用I2S的话我们就可以读取到音频数据了,也就是可以外接功放了。
不过我没用,我选择最省事的耳机,不仅耳机本身的线充当了天线,而且直接把左右声道接到耳机座就行了。

剩下六位是来设置三个GPIO口配置的,应该都能看懂,我就不一个个说了。
接下来是05H。

Bit15是设置中断模式,之前有提过,我们可以设置GPIO2在搜台结束后发送低电平。
我们可以通过bit15设置这个脉冲时间为5ms,或者是低电平一直持续到我们读取寄存器0CH。
Bit14和bit13设置搜索模式,没看懂啥意思,按照默认值来吧。
Bit12保留位。
Bit11~bit8设置搜台的信噪比阈值,就是信号低于这个阈值我们就不当它是个频道。
Bit7和bit6设置LNA输入端口,具体是干什么的不太清楚。
Bit5和bit4保留位。
Bit3~bit0来设置音量大小,数值越大声音越大,不过就算设置为了0还是有点声音。
06H寄存器是来配置I2S总线的,我这边没有用到,所以就不看了。

07H我也没看很懂,不过一般情况也用不到,所以我就这边贴出来,感兴趣的自己看。
那么至此,关于RDA5807FP我们就基本了解了。
接下来轮到我们硬件设计了。

供电部分选择经典的TP4056,根据接的锂电池大小去选择接到TP4056的PROG上的电阻。
同时也可以用Type-C充电和供电。
电源芯片选择TX4401,将供电转为3V3,之前介绍过(偷偷打个广告,详情见公众号“折途想要敲代码”)。

主控芯片选择的是STC32G8K48,20引脚的,我现在DIY基本用的都是STC的,如果性能不够就直接上ESP32。
其实选这个型号是资源冗余了,用STC8都可以的,你们换别的芯片也行。

其实就用个I2C,然后接出了四个中断引脚接按键,再把烧录的接口留出来。
最后就是照着手册抄的RDA5807FP。
最后给大伙看看成品。

代码看附件。
设计图
未生成预览图,请在编辑器重新保存一次BOM
暂无BOM
克隆工程知识产权声明&复刻说明
本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。
请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。








![[精品毕设]分布式设备的物联网控制系统设计|星火计划](http://image.lceda.cn/pullimage/cEBnmqeIIiBzBJIfQEj82mgxXZoi3X7MC0W69LV2.jpeg?x-oss-process=image/resize,w_122,h_85,m_lfit/format,webp)