版本协议

GPL 3.0

标签
专业版
#第11届立创电赛# CH32V305 USB FM 收音机

创建时间:2周前

62 0

描述

<h3 style="line-height:1.8;">* 1、项目功能介绍</h3> <hr> <p>随着时代的发展,大众日常娱乐更加青睐各种视频节目。但是无论如何,FM 广播有着接收成本低廉,分散的注意力有限(迄今为止我只听说过针对司机朋友的交通广播,并未见过针对司机的交通视频)等等优势,因此 FM 广播永远不会消失。</p> <p>同样的,自己制作一个 FM 收音机也是电子爱好者踏入无线电领域的必经之路。</p> <p>这次,使用国产 WCH 出品的 CH32V305 ,配合 RDA5807 制作一个 USB FM 收音机。</p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">*2、项目属性</h3> <hr> <p>原创项目,首次公开</p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">* 3、开源协议</h3> <hr> <p>GPL 3.0 开源协议</p> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><strong><span style="color:#0093e6;">请在竞赛阶段填写 ↓</span></strong></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">*4、硬件部分</h3> <hr> <p>硬件上选择 RDA5807 作为 FM 接收和处理芯片,是上海锐迪科(RDA)推出的一款高集成度单芯片FM收音解决方案。这款芯片支持两种工作模式:全自动收音机模式和单片机控制模式。二者通过上电时引脚的 Strapping 来区分。全自动收音机模式下,上电之后就是一个收音机,通过引脚即可实现选台自动搜索等等功能;单片机控制模式下是通过外部的单片机使用 I2C 接口进行控制,这样可以更加灵活,比如,在外界屏幕上显示当前的频率等等。此外,这个芯片可以通过模拟输出接收的音频,还可以使用 I2S 接口进行输出。I2S 是纯数字型号,最大限度的避免干扰。</p> <p>为了控制RDA5807, 这里选择 CH32V305 作为主控。它是一款支持USB High Speed 的单片机,为了更好的压缩体积,选择QFN28封装的CH32V305GBU6型号。这种封装在保证体积的情况下,提供了足够多的引脚便于实现功能。这个芯片通过I2C 总线控制 RDA5807, 然后通过I2S 接收音频信号,再通过代码将自身模拟为一个 USB 麦克风设备,这样就能将收到的 FM 广播传输到电脑中。</p> <p>需要注意RDA5807 的Pin6 是工作模式选择,上电拉低意味着单片机控制模式。</p> <p>此外,RDA5807 的GPIO0/1/2 分别对应 I2S WS/SD/SCK 功能。</p> <p>为了尽量的提升音质,设计上预留了LP5907MFX-3.3作为 5V转3.3V,但是实际测试下来国产的XC6206P332MR 已经足够。</p> <p><img src="//image.lceda.cn/pullimage/r5S9cD3sVIJCA8mJ5TdLCBnxaZ3r6CGLTa15bouK.png" alt="r5S9cD3sVIJCA8mJ5TdLCBnxaZ3r6CGLTa15bouK.png"></p> <p>为了尽可能保证接收效果,避免干扰,PCB 使用4层板, I2S 信号位于中间层,上下的铜箔层保证I2S 不会干扰 模拟接收。</p> <p><img src="//image.lceda.cn/pullimage/4FZHXCUlSA3Wnu95GEB7qt4JvZCMGG3k9l1Ppbmg.png" alt="4FZHXCUlSA3Wnu95GEB7qt4JvZCMGG3k9l1Ppbmg.png"></p> <p> </p> <p>外壳同样是立创EDA 设计,上下结构通过螺丝进行固定</p> <p style="line-height:1.8;"><img src="//image.lceda.cn/pullimage/A5OXugmur7JwK5hZGV97d7zUTYo2MMgq9GmsAgo7.png" alt="A5OXugmur7JwK5hZGV97d7zUTYo2MMgq9GmsAgo7.png"></p> <h3 style="line-height:1.8;">*5、软件部分</h3> <hr> <p>软件包括两部分:固件的设计和应用程序的设计</p> <p>第一部分:固件设计</p> <p>代码是基于官方的Ch372 例子修改而来,关键代码首先是描述符部分,该设备实现了 <strong>UAC 1.0 </strong><strong>麦克风 + HID</strong> 的复合设备。其中的麦克风是用于设备将FM 音频传递给主机, HID 负责应用程序将命令发送给设备</p> <p><strong>High Speed USB </strong><strong>带有3 </strong><strong>个接口:</strong></p> <p><strong>Interface 0 — </strong><strong>音频控制</strong></p> <ul> <li>拓扑链:Input Terminal (ID=4, Microphone) → Feature Unit (ID=5, 支持静音) → Output Terminal (ID=6, USB Streaming)</li> <li>无端点</li> </ul> <p><strong>Interface 1 — </strong><strong>音频流传输</strong></p> <ul> <li>Alternate 0:零带宽(无端点,空闲状态)</li> <li>Alternate 1:激活流,<strong>EP3 IN</strong><strong>(ISO</strong><strong>)</strong><ul> <li>格式:PCM Type I,<strong>双声道,</strong><strong>16-bit</strong><strong>,48 kHz</strong></li> <li>最大包大小:196 字节(48+1 样本补偿用于速率匹配)</li> <li>HS 模式:bmAttributes = 0x05(Isochronous | Async)</li> </ul></li> </ul> <p><strong>Interface 2 — HID</strong><strong>接口</strong></p> <ul> <li>EP1 IN + EP1 OUT,均为 Interrupt,包大小 64 字节,间隔 1ms</li> <li>HID Report 为 Vendor Defined(Usage Page 0xFF00),64 字节 IN / 64 字节 OUT,用于自定义控制命令</li> </ul> <p>这样设置之后,插入Windows主机就会出现麦克风设备和一个自定的 HID设备。</p> <p><img src="//image.lceda.cn/pullimage/ATsxJmTfC1wvG8cwgFCzMUNOvUbAc2YT55xTDdoo.png" alt="ATsxJmTfC1wvG8cwgFCzMUNOvUbAc2YT55xTDdoo.png"></p> <p> </p> <p>接下来,在USBHS_Device_Endp_Init() 函数中设置端点属性,特别是 USBHSD->ENDP_TYPE = USBHS_UEP3_T_TYPE;  指定表示 <strong>EP3 </strong><strong>的 TX </strong><strong>方向(IN</strong><strong>)设置为 ISO </strong><strong>同步传输类型</strong>。之后的处理就和常见的 Bulk 之类没有太大区别了。</p> <p>需要注意的是,对于音频USB设备,缓冲是必不可少的设计。整体架构是一个 <strong>I2S DMA </strong><strong>双缓冲 → </strong><strong>环形缓冲区 → USB ISO </strong><strong>端点</strong> 的三级流水线,用于吸收 I2S 采样时钟与 USB SOF 时钟之间的频率漂移。</p> <p><strong>第一级:I2S DMA </strong><strong>双缓冲(硬件层)</strong></p> <p>I2S2_Rx[2 × (192/2)] = I2S2_Rx[192 个 uint16]</p> <p>├── 前半([0..95])   — 一个 ISO 包 (192 字节)</p> <p>└── 后半([96..191]) — 一个 ISO 包 (192 字节)</p> <p>DMA1_Channel4 以<strong>循环模式</strong>将 SPI2/I2S 的 RX FIFO 不停搬运到 I2S2_Rx:</p> <ul> <li><strong>HT</strong><strong>(半传输中断标志)置位</strong>:前半已满,DMA 正在写后半 → 主循环安全拷贝前半</li> <li><strong>TC</strong><strong>(传输完成标志)置位</strong>:后半已满,DMA 正在写前半 → 主循环安全拷贝后半</li> </ul> <p>这是经典的<strong>乒乓缓冲</strong>,保证 DMA 写和 CPU 读不冲突。</p> <p><strong>第二级:字节环形缓冲区(软件层)</strong></p> <p>USBHS_EP3_Buf[RINGBUFFERNUMBER × 192] = 1920 字节 (10 包)</p> <p>三个变量管理:</p> <table> <tr> <td> <p><strong>变量</strong></p> </td> <td> <p><strong>含义</strong></p> </td> </tr> <tr> <td> <p><a target="_blank">tail</a></p> </td> <td> <p>写指针(I2S 写入位置)</p> </td> </tr> <tr> <td> <p><a target="_blank">head</a></p> </td> <td> <p>读指针(USB 消费位置)</p> </td> </tr> <tr> <td> <p><a target="_blank">counter</a></p> </td> <td> <p>当前字节数(填充量)</p> </td> </tr> </table> <p>目标填充水位 AUDIO_CENTER = 960 字节(5 包),两侧各留 5 包的漂移余量。</p> <p><strong>第三级:USB </strong><strong>速率自适应(流控层)</strong></p> <p>每次 EP3 的 TX_CTRL 变为 NAK(表示上一包已发出,可准备下一包)时,主循环判断:</p> <p>未预填充 (audio_primed=0):</p> <p>  → 发静音包,等待 counter ≥ 960 字节后置 primed=1</p> <p> </p> <p>预填充完成 (audio_primed=1):</p> <p>  counter > 960+4  →  发 49 个采样帧(196 字节)  ← buffer 偏高,多发</p> <p>  counter < 960-4  →  发 47 个采样帧(188 字节)  ← buffer 偏低,少发</p> <p>  否则             →  发 48 个采样帧(192 字节)  ← 正常</p> <p>  若 counter < nbytes(欠载)→ 发静音,重回预填充阶段</p> <p>是 <strong>异步 ISO </strong><strong>的软件速率匹配</strong>(Async Isochronous),通过每包加减一帧(±4 字节)来平滑 I2S 实际采样率(约 47872 Hz,受 144MHz 时钟精度限制)与 USB 主机消费速率(48000 Hz)之间的差异,避免产生周期性爆音。</p> <p><strong>整体数据流</strong></p> <p>RDA5807 (I2S slave)</p> <p>    │  Philips I2S / 16bit / 48k / Stereo</p> <p>    ▼</p> <p>SPI2 DATAR ──DMA1_Ch4 循环──▶ I2S2_Rx[192](双缓冲)</p> <p>                                  │ HT/TC 标志,主循环轮询</p> <p>                                  ▼</p> <p>                            RingWrite() ──▶ USBHS_EP3_Buf[1920](环形缓冲)</p> <p>                                                  │ 速率自适应,主循环</p> <p>                                                  ▼</p> <p>                                           EP3_Tx[200](临时包缓冲)</p> <p>                                                  │ DMA 地址写入寄存器</p> <p>                                                  ▼</p> <p>                                         USBHSD UEP3 ISO IN ──▶ USB Host</p> <p>固件定义了三个命令通过 USB HID 发送:每次发送 64Bytes,第一个字节为 ‘T表示后面是要设置的频率,为字符串格式,比如:要求设置频率为107Mhz,那么发送给设备的命令是 “T:10700”;此外,设计上通过 RDA5807 接收FM 信号,额外定义一个读取命令 ‘R’ , 后面跟着要读取的寄存器,比如,要读取 RDA5807 的 0x2 寄存器,发送的 HID 命令是:“R2”, 返回16Bits的寄存器值;还有一个写入取命令 ‘R’,比如,要对RDA5807 的 0x2 寄存器写入 34,发送的 HID 命令是:“W2=34”</p> <p>烧录上述固件后,可以将设备设置为“监听”模式,这样设备的声音可以通过扬声器不停的播放出来,然后使用 HID 工具直接发送命令这样即可方便的进行调试。</p> <p>之后,开始Window下应用程序的设计。</p> <p>选择使用 C# .net 4.8 ,这个版本Windows10/11 内置直接支持,无需额外安装库。同时可以将用到的库都打包在同一个 EXE 中便于分发使用。</p> <p><img src="//image.lceda.cn/pullimage/Y7VtZciSiVngRQAEbsp29G0aCK4aMybtIGRWAvFT.png" alt="Y7VtZciSiVngRQAEbsp29G0aCK4aMybtIGRWAvFT.png"></p> <p>代码基本流程是</p> <ol> <li><strong>构造 RadioDeviceController</strong> → 通过 HidSharp 库按 VID=0x1A84, PID=0xFE09 搜索 USB 设备并打开 HID 流</li> <li><strong>加载配置</strong> → 从 radio_config.json 读取预设电台和扫描结果</li> <li><strong>枚举录音设备</strong> → AudioPlayer.GetAllRecordingDeviceNames() 列出可用的 USB 音频输入设备</li> <li><strong>检查麦克风权限</strong> → 无设备则弹窗警告</li> </ol> <p>然后等待用户操作</p> <p> </p> <h3 style="line-height:1.8;">*6、BOM清单</h3> <hr> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">请输入内容…</span></p> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">注:项目涉及的BOM清单。在<span style="text-decoration:underline;"><a href="https://lceda.cn/editor" target="_blank">嘉立创EDA</a> </span>生成/上传设计文件后,BOM将自动生成至项目详情;建议包括型号、品牌、名称、封装、采购渠道、用途等内容。具体内容和形式应以表达清楚项目构成为准。 </span></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">*7、大赛LOGO验证</h3> <hr> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><img src="//image.lceda.cn/pullimage/ySMVQ5ukNA15ABpnaqyR4oAPPMbC2T3xiWAtp0lC.png" alt="ySMVQ5ukNA15ABpnaqyR4oAPPMbC2T3xiWAtp0lC.png"></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">* 8、演示您的项目并录制成视频上传</h3> <hr> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">视频要求:请横屏拍摄,分辨率不低于1280×720,格式Mp4/Mov,单个视频大小限50M内;</span></p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">视频标题:立创电赛:{项目名称}-{视频模块名称};如立创电赛:《自动驾驶》-团队介绍。</span></p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">视频冲榜:项目制作过程中,可随时录制视频上传至B站、小红书、视频号、抖音号,<a style="text-decoration:underline;" href="https://doc.weixin.qq.com/smartsheet/form/1_wpmhMpBwAAfrKELBBSNdSqJrorjTQE8Q_600d71" target="_blank">冲榜人气奖励 ></a>,优秀项目可获得立创官方全域曝光机会;</span></p> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><span style="font-size:14px;"><a style="text-decoration:underline;" href="/posts/b2b65ad17ac34080a318a5ab47a632c2" target="_blank">前往查看更多详情 ></a></span></p> <p style="line-height:1.8;"> </p>

文档

BOM

附件

附件名 下载
FMTestV2.7z
CH32V305USB_FM.zip

评论(0)

  • 表情
    emoji
    小嘉工作篇
    小嘉日常篇
  • 图片
成功
工程所有者当前已关闭评论
goToTop
svg-battery svg-battery-wifi svg-books svg-more svg-paste svg-pencil svg-plant svg-ruler svg-share svg-user svg-logo-cn svg-double-arrow