发新帖本帖赏金 150.00元(功能说明)我要提问
返回列表
打印
[RISC-V MCU 应用开发]

基于ESP32层+RDA5807的高灵敏数字选台FM收音机

[复制链接]
3218|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 gaoyang9992006 于 2023-11-15 17:58 编辑

#申请原创# @21小跑堂


收音机作为90年之前出生的人来讲是一种放不下的情怀,儿时家里穷,没电视,收音机是唯一获取世界信息与高端娱乐的家用电器,就跟另外一件家电手电筒一样的重要地位。
今年世界战乱不断,很担心发生第三次世界大战,于是决定做一台收音机。这也是我第一次尝试做基于现代数字芯片的收音机。上学时候做过传统的模拟收音机。
那么开始讲述这台收音机怎么做的吧。

https://bbs.21ic.com/icview-3336534-1-1.html
这是我开始这项DIY项目时候的第一个贴
原理图如下所示

采用LCD显示内容,通过一个旋转编码器进行选台和调节

由于本人是左撇子,所以旋钮放在左边了。

背后预留了BK1088E模块的接口,用于调试下一个项目全波段收音机。
上实物图

第一行显示FM,频率值,音量+声道(色块长度表示音量,色块双绿色条表示立体声,如果是单声道就显示一整块黄色音量条)
第二行显示信号强度
第三行显示当前模式:模式0表示正常模式,此时滚动轮子切换电台(自动搜索下一个电台),如果按一下滚轮进入模式+1,模式1为音量调节,模式2为手动选台。
第四行为频率刻度,第五行为大的数码管字体的当前频率。
通过以下函数实现基础UI的绘制
void UI_Init(void)
{
  tft.initR(INITR_BLACKTAB);  //初始化屏幕
  tft.fillScreen(Display_Backround_Color);
  tft.setFont();//初始化字体
  tft.setTextColor(Display_Text_Color);
//绘制刻度线
  tft.drawFastHLine(0, 65, tft.width(), ST77XX_RED);
  for(uint8_t x=4;x<128;x=x+12)
  {
    tft.drawFastVLine(x, 65, 5, ST77XX_BLUE);
  }

//  tft.drawFastVLine(4+(((rx.getFrequency()/100.0)-76.0)*(120.0/(108-76))), 60, 5, ST77XX_GREEN);
  tft.drawFastVLine(4+(((nowFre.toFloat())-76.0)*(120.0/(108-76))), 60, 5, ST77XX_GREEN);

  tft.setCursor(0, 72);
  tft.print("76");
  tft.setCursor(110, 72);
  tft.print("108");


  //绘制线框,用于显示频率
  tft.drawRect(0,0,tft.width(),15,ST77XX_GREEN);
  tft.drawRect(2,2,18,11,ST77XX_BLUE);
  tft.drawRect(25,2,64,11,ST77XX_BLUE);

  tft.setTextSize(1);
  tft.setCursor(5, 4);
  tft.print("FM");
  tft.setCursor(28, 4);
  tft.print(nowFre);
  tft.setCursor(68, 4);
  tft.print("MHz");

  //绘制线框,用于显示信号强度
  tft.drawRect(0,20,tft.width(),15,ST77XX_GREEN);
  tft.drawRect(2,22,28,11,ST77XX_BLUE);
  tft.drawRect(67,22,58,11,ST77XX_BLUE);

  tft.setTextSize(1);
  tft.setCursor(5, 22+2);
  tft.print("RSSI");
  tft.setCursor(70, 24);
  tft.print(nowRssi);
  tft.setCursor(100, 24);
  tft.print("dbUv");
//设置模式显示位置
  tft.setTextSize(2);
  tft.setCursor(10, 40);
  tft.print("MODE : 0");
//测试数码管字体
  tft.setFont(&digital_718pt7b);
  tft.setTextSize(1);
  tft.setCursor(5, 120);
  tft.print(nowFre);
  tft.setFont();//恢复默认字体
}
以下是更新频率显示盒更新信号强度的方法
void update_Fre(void)
{
  //更新频率显示
  tft.setTextSize(1);
  tft.setTextColor(Display_Backround_Color);
  tft.setCursor(28, 4);
  tft.print(nowFre);
  tft.drawFastVLine(4+(((nowFre.toFloat())-76.0)*(120.0/(108-76))), 60, 5, Display_Backround_Color);//清理吊当前的频率指示针
  //测试数码管字体
  tft.setFont(&digital_718pt7b);
  tft.setTextSize(1);
  tft.setCursor(5, 120);
  tft.print(nowFre);

  tft.setFont();//恢复默认字体,更新频率显示
  tft.setTextColor(Display_Text_Color);
  tft.setCursor(28, 4);
  nowFre = String(rx.getFrequency()/100.0);
  tft.print(nowFre);
  tft.drawFastVLine(4+(((nowFre.toFloat())-76.0)*(120.0/(108-76))), 60, 5, ST77XX_GREEN);//显示新的频率指示针
  //测试数码管字体
  tft.setFont(&digital_718pt7b);
  tft.setTextColor(ST77XX_YELLOW);
  tft.setCursor(5, 120);
  tft.print(nowFre);
  tft.setFont();//恢复默认字体
}

void update_Rss(void)
{
  //更新信号强度显示
  tft.setTextSize(1);
  tft.setTextColor(Display_Backround_Color);
  tft.setCursor(70, 24);
  tft.print(nowRssi);
  tft.setTextColor(Display_Text_Color);
  tft.setCursor(70, 24);
  nowRssi = String(rx.getRssi());
  tft.print(nowRssi);

//如果是立体声就绘制一个绿色矩形,如果是单声道就绘制一个黄色矩形,矩形的长度表示音量,
  if(rx.isStereo())
  {
    tft.fillRect(90,5,35,5,Display_Backround_Color);
    tft.fillRect(90,5,2+(rx.getVolume()*2),5,ST77XX_GREEN);
    tft.fillRect(90,7,35,1,Display_Backround_Color);//立体声改成双条线
  }
  else
  {
    tft.fillRect(90,5,35,5,Display_Backround_Color);
    tft.fillRect(90,5,2+(rx.getVolume()*2),5,ST77XX_YELLOW);
  }
}
处理编码滚轮的滚动与按键的方法
  if(R_Encoder_Active !=0)
  {
    if(R_Encoder_Active ==1)
    {
      switch (radio_mode)
      {
        case 0: rx.seek(RDA_SEEK_WRAP, RDA_SEEK_UP, showStatus); break;
        case 1: rx.setVolumeUp();                                break;
        case 2: rx.setFrequencyUp();                             break;
        default:break;
      }
      
    }
    else
    {
      switch (radio_mode)
      {
        case 0: rx.seek(RDA_SEEK_WRAP, RDA_SEEK_DOWN, showStatus); break;
        case 1: rx.setVolumeDown();                                break;
        case 2: rx.setFrequencyDown();                             break;
        default:break;
      }
    }
    R_Encoder_Active =0;
    delay(100);
    update_Fre();
    update_Rss();
  }
  if(Button_Active == 1)
  {
    radio_mode++;
    Button_Active = 0;
    if(radio_mode>5) radio_mode = 0;
    tft.fillRect(80,40,32,14,Display_Backround_Color);
    tft.setTextSize(2);
    tft.setCursor(90,40);
    tft.print(String(radio_mode));
    delay(100);
    update_Fre();
    update_Rss();
  }
主程序初始化方法
  EC11_Init();

  Wire.begin();  // 初始化I2C总线,用于RDA5807通信
  rx.setup();
  rx.setVolume(2);
  rx.setLnaPortSel(3);
  rx.setFrequency(9750); // It is the frequency you want to select in MHz multiplied by 100.
  delay(250);
  rx.setAFC(true);    // Sets Automatic Frequency Control
  UI_Init();

经过实测,该芯片灵敏度非常高,在南京地区户外可以搜到将近30个电台,在写字楼内可以搜到17个电台。
部分电台频率可以看开头那连接的帖子内容。

附加:该芯片收音机的灵敏度跟天线电路关系很大,只有信号输入可靠才能解调出较多清晰的电台。
如果直接一根导线接入,很难收到较好的效果,这也是上一个贴有人说信号强度不够的原因。
以下天线滤波电路是手册给出的。

上图是RDA5807MP封装推荐的,下图是RDA5807M推荐的滤波电路。

另外可以通过仿真软件对天线滤波电路的传输特性进行仿真计算,实际上还要根据自己布线的情况进行参数调整以达到最佳。
下面是对应帖子版本的工程代码包
ST7735_RDA5807.zip (21.59 KB)
下面是另外一个版本的,还是调试修改中,从RDA5807换成了全波段的BK1088E,目前在编写通用的驱动函数中。利用网上开源的已经没问题了,想写一个属于自己的驱动函数,基于C语言的,正在调试修改中。


使用特权

评论回复

打赏榜单

21小跑堂 打赏了 50.00 元 2023-11-15
理由:源码包追加奖励

21小跑堂 打赏了 100.00 元 2023-11-15
理由:恭喜通过原创审核!期待您更多的原创作品~

评论
21小跑堂 2023-11-15 17:31 回复TA
设计十分精巧的收音机,小巧且精致,功能比较完善,很不错的DIY项目。上传源码可获得更高的打赏哦~ 

相关帖子

沙发
gaoyang9992006|  楼主 | 2023-11-15 18:01 | 只看该作者
制作总结:由于屏幕占用了较多的IO接口,而使用的ESP32-C3可用IO较少,这样没法实现更多的的按键功能,有点捉襟见肘,所以我想在基于BK1088E的全波段收音机DIY项目中使用自己开发的C语言库,这样就可以方便的在任意单片机上使用了。

使用特权

评论回复
板凳
中国龙芯CDX| | 2023-11-29 12:46 | 只看该作者
屏幕可以使用SPI通讯方式是不是会节约点呢

使用特权

评论回复
地板
gaoyang9992006|  楼主 | 2023-11-29 14:36 | 只看该作者
中国龙芯CDX 发表于 2023-11-29 12:46
屏幕可以使用SPI通讯方式是不是会节约点呢

用的就是SPI,

使用特权

评论回复
5
LOVEEVER| | 2023-11-29 19:43 | 只看该作者
楼主这个绘图软件是嘉立创嘛,看着很赞

使用特权

评论回复
6
gaoyang9992006|  楼主 | 2023-11-29 20:27 | 只看该作者
LOVEEVER 发表于 2023-11-29 19:43
楼主这个绘图软件是嘉立创嘛,看着很赞

是的,用的嘉立创EDA专业版

使用特权

评论回复
发新帖 本帖赏金 150.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:西安公路研究院南京院
简介:主要工作从事监控网络与通信网络设计,以及从事基于嵌入式的通信与控制设备研发。擅长单片机嵌入式系统物联网设备开发,音频功放电路开发。

1961

主题

15931

帖子

208

粉丝