SI47xx系列FM收发芯片RDS应用详解:SI4711发射与SI4730接收 简介本资源是一套面向嵌入式开发工程师与电子设计爱好者的SI47XX系列广播芯片实战开发包聚焦SI4730 RDS功能在STC89C516单片机平台上的完整实现与调试验证。资源解决RDS数据解析、芯片底层驱动、LCD人机交互等典型集成难题适用于汽车音响、智能收音机、教学实验等场景适合具备C语言基础和单片机开发经验的中级学习者。压缩包共14个文件3.28MB含6个头文件.h定义寄存器、接口及RDS协议结构体5个源文件.c涵盖主控逻辑、按键处理、LCD显示驱动及SI4730初始化与RDS解码核心代码另有3份关键PDF文档含AN332应用笔记、Si4720/4704数据手册支撑原理理解与硬件适配。已有234人学习下载提供从芯片通信配置、RDS数据流解析到1602液晶实时显示的端到端可运行方案目录模块划分清晰便于快速定位驱动层、应用层与调试支持代码。 如果你最近在下载站翻到过si47xx.zip这类压缩包或者在某开源群里看到有人甩了一串4730 rds code的文件名那多半是在折腾 Silicon Labs 的 SI47xx 系列芯片。这套芯片在 FM 收发方案里一直很有存在感SI4711 负责把音频变成射频信号发出去SI4730 负责把空中的调频信号解调出来而 RDS 则是嵌在 FM 信号里的那串看不见的文字数据流。标题里同时出现 SI4711、SI4730、SI47xx 和 RDS code说明这大概率是一个跨发射和接收两端的完整 RDS 工程包。这篇文章我会从 SI47xx 家族的实际选型讲起把 RDS 的底层数据结构、发射端的寄存器操作、接收端的解码流程全部拆开最后附上调试记录和避坑清单。适合正在做微型 FM 电台、校园广播文字台、车载蓝牙歌词屏、或者想用一块 STM32/ESP32 把 RDS 彻底搞明白的开发者。不管你是第一次接触这系列芯片还是已经调通基础收发但卡在 RDS 上这篇都能给你省下不少翻数据手册的时间。1. 先认识 SI47xx 家族发射和接收不是同一颗片1.1 型号差异与选型建议SI47xx 是一个很大的产品线经常被大家混着叫。实际上这颗芯片在出厂时就分成了两大阵营一类是发射器一类是接收器。SI4710、SI4711、SI4712、SI4713 属于发射器它们的职责是把音频信号调制到 76MHz 到 108MHz 的 FM 频段上并发射出去。SI4730、SI4732、SI4734、SI4735 属于接收器负责接收和解调广播信号。SI4730 是这里面非常经典的 FM/AM/SW 接收方案很多开源收音机项目都用它。具体选型时如果你只是需要发射 FM 并附带 RDS 文字信息SI4711 是性价比很高的选择。SI4713 比 SI4711 多了立体声编码、音频动态控制等能力但纯做 RDS 文本播报的话SI4711 完全够用。如果要做接收端并且有解码 RDS 的需求SI4730 的 D60 后缀版本基本都带 RDS 功能SI4734 和 SI4735 在 SI4730 的基础上还支持更多频段和 SSB 模式适合进阶玩家。需要注意后缀是 D50 还是 D60老版本固件对 RDS 的支持不完整。这个家族还有个优点所有型号的内部控制寄存器风格高度统一都是通过 I2C 发送命令和属性Property来完成操作。也就是说你在 SI4711 上调通的那套 I2C 读写逻辑换到 SI4730 上只需要改动设备地址和部分模式参数就能复用。这也是为什么你拿到一个si47xx.zip代码包后会发现里面同时带了 si4711 和 si4730 两个平台的控制代码。1.2 I2C 从机地址与基本接线SI47xx 系列走的是标准 I2C 接口但发射器和接收器的设备地址不一样。SI4711 的 7 位 I2C 地址是 0x11SI4730 的 7 位地址是 0x63。Arduino 或者 STM32 的 Wire 库在发送时会把地址左移一位作为 8 位地址所以你会看到很多代码里写的是Wire.beginTransmission(0x11 1)或者0x63 1。如果自己写底层驱动一定要搞清楚这个移位关系否则会持续收到 NACK。接线方面除了 I2C 的 SDA 和 SCLSI47xx 还需要外部晶振。SI4711 一般用 32.768kHz 的无源晶振配合芯片内部的 PLL 倍频出发射载波。SI4730 也类似。没有晶振或者晶振频率不对芯片上电后会一直不响应命令这是最容易被忽略的问题。另外SI4711 的射频输出脚RFOUT需要接一段匹配天线或者至少 50Ω 的假负载否则输出功率会异常RDS 数据也就很难被正常接收。实际调试时我总是先在 RFOUT 上接一根约 5cm 的导线够让旁边的接收板收到信号就行别一上来就追求最大功率。芯片型号方向7位I2C地址频段RDS能力SI4711发射0x1176-108MHz支持适合 PS/RT 播报SI4713发射0x1176-108MHz支持带立体声编码SI4730-D60接收0x63FM/AM/SW/LW支持可解码 RDSSI4734-D60接收0x63FM/AM/SW/LW支持扩展频段SI4735-D60接收0x63FM/AM/SW/LW/SSB支持适合业余无线电2. RDS 内容长什么样SI47xx 在硬件层帮你干掉了什么2.1 RDS 的 104 位组结构RDSRadio Data System是在 FM 立体声信号里叠加的一路低速数字数据流专门用来传输电台名称、节目类型、歌词、交通信息、时钟等附加信息。它的基本单位不是一个字节而是一组 104 位的数据叫做“组”Group。每一组由 4 个块Block组成分别是 Block A、B、C、D每个块是 16 位有效数据后面还跟着 10 位 CRC 校验码。这 10 位 CRC 非常关键它保证了接收端能够在动态信号中准确找到每组数据的起始位置而不是靠简单的字节对齐。Block A 固定放 PI 码也就是电台的识别码相当于每个 RDS 电台的身份证。Block B 的含义根据组类型变化组类型是一个 4 位的数字比如 0A 组、2A 组、3A 组、4A 组。每种组类型用途不同最常用的就是 0A 组和 2A 组。0A 组负责传 PSProgram Service广播电台名称最多 8 个字符2A 组负责传 RadioText也就是更长的滚动文本最长 64 个字符。Block C 和 Block D 的 32 位数据则用来装组类型对应的具体内容。这套结构对大多数应用来说有点晦涩但好消息是 SI47xx 在硬件层面已经把最难的 CRC 校验和射频调制都做好了。发送时你只需要把 104 位里的 64 位有效数据填进去芯片会自动计算校验位并合成发射信号。接收时芯片也会自动完成同步和 CRC 校验你从状态寄存器里读到的基本是已经校验过的有效块。这对开发者来说省掉了大量数字信号处理的工作。2.2 SI47xx 的 RDS 简化模型在 SI47xx 芯片的世界里RDS 不是靠你手动控制每一比特的波形而是通过一组属性寄存器完成的。发射端最核心的属性是 0x0400、0x0401 和 0x0402。0x0400 是 PI 码0x0401 是 PS 消息文本0x0402 是 RDS 数据 FIFO你把要发送的组数据写进 FIFO芯片就会在后台自动按顺序发出去。接收端则是 0x0500 附近的一组属性用来打开 RDS 功能、查询状态、读取解码后的块数据。你可以把 SI47xx 的 RDS 当成一个“文本投递信箱”发射端往信箱里塞内容芯片内部排队、附加校验、调制到射频接收端芯片自动从射频里把内容捞出来并排成队列你只需要周期性地去信箱取信。这个模型的优势在于即使你对 RDS 协议完全不了解只要会填几个属性寄存器也能快速做出一个能播报 PS 和 RadioText 的小电台。遇到更复杂的 RT、EON 等高级功能时才需要深入协议细节日常项目用不到。我在实际项目里最常用的两种模式就是用 0A 组轮播电台名用 2A 组轮播一段较长的说明文字。如果你的应用只显示 8 个字符以内的信息0A 组的 PS 字段就够了因为它会被接收机自动周期重复。如果超过 8 个字符比如要显示“校园广播站今日歌单”这种就必须用 2A 组的 RadioText并且要在接收端自己拼装分段文本。3. SI4711 发射端把 RDS“写”出去3.1 上电与 POWER_UP 参数要让 SI4711 进入 FM 发射模式第一步是发送 POWER_UP 命令。命令码是 0x01后面跟两个参数第一个参数里最关键的是 FUNC 字段它决定了芯片工作在发射模式还是接收模式。对于 SI4711FUNC 要设置为发射器模式典型参数是 0x05 左右同时要把 XOSCEN 置 1让内部晶振起振。第二个参数一般用 0x0C表示模拟音频输入和默认输出设置。如果你拿到的是现成库库函数已经封装好这一步但自己移植时一定要对着数据手册确认这两个字节没有传反。发送 POWER_UP 之后不能立刻往下发命令必须等待 CTS 位变成 1。SI47xx 的 CTS 表示芯片已经准备好接收下一条命令靠读取响应状态寄存器来确认。一个常见的坑是上电后立刻发送下一条命令芯片还在启动过程中命令被直接丢弃后续设置频率、设置 RDS 全部没有反应但 I2C 又不会报错非常难排查。所以我一般在初始化函数里加一个等待 CTS 的循环超时时间给到 500ms确保芯片稳定就绪。3.2 设置 FM 载波频率发射频率是通过 FM_TUNE_FREQ 命令设置的命令码是 0x30。这个命令的算频率单位是 10kHz不是 Hz。比如要发 95.0MHz就要把 9500 传给命令也就是 9500 十进制等于 0x251C。很多第一次接触的人会直接传 95000000结果芯片把频率算到几千兆赫兹然后怎么都不出信号。类似的要发 87.5MHz就传 8750对应 0x222E。代码上大概是这样uint16_t freqKhz10 9500; // 95.0MHz单位10kHz uint8_t cmd[] { 0x30, // FM_TUNE_FREQ 0x00, // 天线电容默认 0x00, // 保留 (freqKhz10 8) 0xFF, freqKhz10 0xFF }; writeI2c(0x11, cmd, sizeof(cmd)); waitCts();如果你用的是 SI4713 这类支持自动搜台的芯片命令参数会更多一点但固定频点发射用这种方式最简单。设置完频率后建议读一次响应确认 FREQ 字段和预期一致。有些模块因为晶振偏差实际输出频率会偏移几百赫兹到几千赫兹虽然听感不明显但接收机的 RDS 解码对载波频率偏差比较敏感偏差太大会导致 RDS 反复掉字。3.3 写入 PI、PS 和 RT 文本设置好载波频率后就可以开始写 RDS 信息了。第一步是写 PI 码属性号 0x0400写一个 16 位值。PI 码可以随便定但最好在合法范围内选择一个不容易和别人冲突的数值。很多代码包里写的是 0x1234或者 0x0100 这种测试值实际使用时你可以根据项目自定义。然后是 PS 文本属性号 0x0401。PS 最多 8 个字符由于属性写入一次最多传 4 个字节所以 8 个字符要分两次写。比如 PS 内容为“MYRADIO!”// 第一次写前4个字符 sendProperty(0x0401, M, Y, R, A); // 第二次写后4个字符 sendProperty(0x0401, D, I, O, !);sendProperty 的本质是发 SET_PROPERTY 命令命令码 0x12格式是属性号高字节、属性号低字节、数据字节一直到 4 个为止。这个命令在 SI47xx 里非常重要后续所有 RDS 配置都是通过它完成的。可能有人会问PI 和 PS 都设置了为什么接收机还是显示不了文字因为你只设置了 PS 的底层寄存器还没有往 FIFO 里写入“0A 组”。RDS 发射不会自动产生 0A 组数据它只会发送你明确写进 FIFO 的内容。所以必须主动把 0A 组的 4 块数据组好送进 0x0402 属性。这个细节最容易漏漏掉的症状就是接收机能听到声音但收音机屏幕上永远没字。3.4 发送 0A/2A 组以 0A 组为例接收机上的电台名字就是靠它循环播报的。0A 组的 Block A 固定是 PI 码不需要你在 FIFO 里重复写芯片会自动从 0x0400 属性取值。Block B 的低 4 位是当前分段索引因为 0A 组一次只能带 2 个 PS 字符8 个字符需要 4 组 0A 才能传完所以索引从 0 到 3 循环。Block C 和 Block D 各放两个字符的 ASCII 码。假设 PS 是“MYRADIO!”那么四组 0A 的分组内容应该是分组索引Block CBlock D携带字符0M YR AMYRA1D IO !DIO!2重复第0组重复第0组MYRA3重复第1组重复第1组DIO!把 Block B/C/D 组装成一个 6 字节数据写入属性 0x0402。下面是连续发送 4 组 0A 的简化 C 代码const char* ps MYRADIO!; uint8_t blockBBase 0x0400; // 0A组类型PTY、TP等先填0 for (int seg 0; seg 4; seg) { uint16_t blockB (0 12) | (seg 0x0F); // 组类型0A低4位为分段索引 uint16_t blockC (ps[seg * 2] 8) | ps[seg * 2 1]; uint16_t blockD (ps[seg * 2 2] 8) | ps[seg * 2 3]; uint8_t data[6] { blockB 8, blockB 0xFF, blockC 8, blockC 0xFF, blockD 8, blockD 0xFF }; sendRdsFifo(data, 6); }这里有个关键点组类型 0A 的 Block B 高 4 位是 0低 4 位是索引中间还夹杂 TP、PTY、TA 等字段。如果你的接收机对 PTY 类型敏感可以把 PTY 填进去但大多数场景填 0 也能正常显示。RadioText 的 2A 组原理类似区别是低 4 位索引的长度是 0 到 15且每组携带 4 个文本字符。组类型 2 的 Block B 高 4 位是 0010所以 Block B 的基础值要换成 0x2000。在写 RT 文本时要记得处理好分段和循环。RDS 接收机是“攒齐所有分段才显示完整文本”的逻辑如果你只发送其中某几个分段或者分段顺序跳变接收机要么显示不全要么一直卡在旧文本上。最稳妥的做法是每 1 到 2 秒循环发送全部分段发送间隔尽量均匀。这个习惯在我后来用真实收音机测试时被证明比任何协议细节都重要。4. SI4730 接收端把 RDS“读”回来4.1 初始化接收器并打开 RDSSI4730 的初始化流程和 SI4711 很像也是先发 POWER_UP然后设置频率但功能参数要改成接收模式。以 95.0MHz 为例POWER_UP 的 FUNC 字段要置为 FM 接收机模式然后设置接收频率。频率单位同样是 10kHz所以 95.0MHz 对应 9500。很多基于 PU2CLR 库的开源工程已经封装了radio.setup()和radio.setFrequency()但底层就是这条 I2C 链路。要把 RDS 功能打开需要设置属性 0x0500也就是 RDS_CONFIG。常见做法是置位 RDS 使能位并同时打开 RDS 中断。有些代码还会清一次 FIFO确保之前残留的脏数据不会干扰后续读取。打开之后芯片会在后台不断接收并校验 RDS 组数据不需要你干预。// 发送器用0x11接收器用0x63别用混 sendProperty(0x63, 0x0500, 0x0001); // 使能RDS clearRdsFifo(0x63); // 清空RDS FIFO这里的属性值是示意值具体位宽和含义要参考你所用芯片版本的编程指南。SI4730 的 D60 版本和更老的 D50 版本在 RDS 相关的寄存器排列上略有差异如果你用的是 D50必须先查清楚它是否真的支持 RDS。我踩过这个坑手头有一颗 SI4730-D50 老库存折腾了半天始终读不到任何块数据后来换 D60 问题直接消失。4.2 中断与状态读取RDS 数据到达后可以有两种方式获取。第一种是中断方式让芯片的 GPIO 或者 INT 脚拉低MCU 检测到电平变化后主动去读状态。第二种是轮询方式MCU 每 20ms 到 50ms 读取一次状态寄存器看到有新的 RDS 块就取走。对大多数项目来说轮询就够用因为 RDS 数据率本身只有大约 11.4 波特一组 104 位数据约要 87ms 才能传完不需要很激进的中断处理。读取状态时芯片会返回一组块数据。你会拿到 Block A 到 Block D 的 16 位数值以及每个块对应的错误标志。错误标志很重要尤其是在信号边缘或者天线位置不好的情况下错误块会随机出现。如果你不管错误标志直接解码PS 和 RadioText 就会时不时蹦出乱码。正确做法是只有四个块的错误标志都为 0 时才去解码任何一块有错整组丢弃。这个逻辑听起来简单但在写代码时很多人只顾着取数忽略了校验导致最终显示质量很差。// 伪代码读取并检查一组RDS RdsBlock block; readRdsBlock(block); if (block.errorA 0 block.errorB 0 block.errorC 0 block.errorD 0) { decodeRdsGroup(block); }关于“校验位错误”还要多说一句。SI47xx 接收机在信号弱时不仅会出现块错误还可能出现“部分块正确、部分块错误”的情况。如果你只检查了 Block B 的错误就解码也许偶尔能碰对但长期运行一定会出问题。我自己的项目里曾为了一点点性能提升跳过了 Block D 的校验结果在运动状态下接收时每隔几分钟就出现一个乱码字符最后把校验补回来才彻底解决。4.3 解码 PS 与 RadioText拿到经过校验的块数据后下一步是把 0A 组和 2A 组翻译成人类可读的文本。解码 0A 组时先看 Block B 的低 4 位得到当前分段索引。0A 组总共有 4 个分段每个分段携带 2 个字符所以 PS 的 8 个字符是分 4 次凑齐的。你需要在内存里维护一个 8 字节的数组每收到一个分段就填充对应位置直到 4 个分段全部到齐才认为 PS 完整可用。RadioText 更麻烦一些2A 组最多有 16 个分段每个分段携带 4 个字符拼出一个最长 64 字符的文本。解码时要注意两件事第一是 2A 组的 Block B 高 4 位是 0010而 0A 组是 0000不要混第二是文本 AB 标志它告诉接收机当前文本是全新的还是追加的。如果文本 AB 标志跳变说明电台换了新文本这时候应该清空旧的 64 字节缓冲区重新开始。忽略这个标志的后果是电台切换文字内容后接收机屏幕经常把新旧文字拼在一起。下面是一个非常精简的 2A 组文本拼接逻辑uint8_t rtBuffer[64]; int rtSegCount 0; int rtSegTotal -1; if ((blockB 12) 2) { int seg blockB 0x0F; int textAFlag (blockC 15) 0x01; if (textAFlag ! lastTextAFlag) { rtSegCount 0; rtSegTotal -1; memset(rtBuffer, 0, sizeof(rtBuffer)); lastTextAFlag textAFlag; } rtBuffer[seg * 4 0] (blockC 8) 0xFF; rtBuffer[seg * 4 1] blockC 0xFF; rtBuffer[seg * 4 2] (blockD 8) 0xFF; rtBuffer[seg * 4 3] blockD 0xFF; rtSegCount | (1 seg); if (rtSegTotal 16) rtSegTotal 16; if (rtSegCount 0xFFFF) { // 全部分段到齐上报完整文本 onRadioTextReady(rtBuffer); } }严格来说2A 组的 Block C 和 Block D 最高位还带有 C1、C2 标志上面的代码直接用 0xFF会忽略标志位对纯文本显示影响不大但你要在正式产品里做严谨解码必须把标志位和字符位分开处理否则某些电台的 RadioText 会出现个别字符错位。5. 调试经验和常见问题速查5.1 发射端 RDS 不出去的排查顺序我在调试 SI4711 时遇到最多的问题是“收音机有声音但屏幕上没有字”。遇到这种情况我会按下面的顺序排查先确认 0x0400 的 PI 码已经写入再确认 0x0401 的 PS 文本写入成功最后确认 0x0402 的 FIFO 里有数据在循环发送。FIFO 里有没有数据最直接的办法是调用一次 GET_INT_STATUS看 FIFO 相关标志位是否为空。如果为空说明组数据根本没有进到芯片里问题多半在发送的属性地址或者数据长度不对。第二步是检查发射频率和接收频率是否一致。如果你用 SI4711 发 95.0MHz接收机却调在 95.1MHz音频可能只是轻微博离但 RDS 解码会非常不稳定甚至完全无法同步。FM 广播信号里RDS 对精确的载波频率和信号质量要求比音频高很多频率偏了哪怕 0.1MHz 都可能让 RDS 失灵。第三步是看射频输出端是否有负载。RDS 信号叠加在 FM 主载波上如果天线开路或者负载阻抗完全不对芯片内部功率放大器会处于异常状态输出频谱出现杂散RDS 子载波甚至会被压制。建议在调试时用一个固定 50Ω 的假负载至少别让天线悬空。现象可能原因解决办法有声音没RDS0x0402 FIFO空循环写入0A/2A组有声音没RDS发射频率偏用频率计校正载波RDS时有时无天线负载异常接50Ω假负载或良好天线PS只显示一半0A分段索引不循环按0-3周期发送RT文字新旧混合忽略文本AB标志标志变化时清空缓冲5.2 接收端乱码与缺字的处理SI4730 接收端最典型的故障是 PS 偶尔乱字、RadioText 断断续续。先说乱字绝大多数原因是错误校验没做全。只要有一个错误块混进了解码流程字符就会变。我建议在接收代码里把错误块计数和正确块计数分别统计如果错误率超过 20%先改善天线位置或信号强度而不是调整解码逻辑。缺字的问题则多半出在分段处理上。PS 的 8 个字符分布在 4 个 0A 分段里接收机必须全部收到才能显示。如果你只发送了 0 到 1 两个分段或者发送间隔不均匀导致某些分段被 FIFO 覆盖接收端就不可能凑齐。RadioText 也一样16 个分段一个都不能少。调试时可以打日志看每个分段索引的到来顺序尤其要注意是否乱序。RDS 本身是一个串行数据流正常情况下分段应该是依次到达的乱序往往是发送端 FIFO 写入太频繁造成的。信号弱导致的“字幕闪烁”也很常见。这个时候我会把接收天线换成稍长的鞭状天线或者把两个板子靠近一点。SI4730 接收 RDS 的最低电平比解调音频要略高所以在信号临界区音频听起来还能接受但 RDS 已经无法稳定同步了。这是芯片特性不是代码 bug不用在软件上死磕。5.3 为什么电视/车机识别不了还有一个比较隐蔽的坑很多项目在电脑上用自己的解码程序测试没问题但放到车机或者商品收音机上RDS 完全不显示。原因是 RDS 里有一些可选字段比如 PTY、TP、TA虽然 PS 和 PI 是核心但不同接收机会对这些字段有不同的处理策略。有些车机只有收到 TP 标志后才显示交通公告有些设备要求 PI 码不能是 0x0000否则拒绝显示任何 RDS 信息。所以我建议在发送端把 PI 设置成一个非 0 的随机测试值同时把 PTY 填成合法值比如 4 代表流行音乐TP 暂时置 0。这样兼容性会好很多。另外要注意 RBDS 和 RDS 的差异。日本和北美常用的 RBDS 标准里组类型的使用和欧洲 RDS 略有区别。SI47xx 本身支持两种模式但你需要确保发射端和接收端的区域模式一致。如果发射端用了 RDS 的组 2A接收端却按 RBDS 的组 2A 解码文本内容可能不显示或错位。对于国内项目一般按欧洲 RDS 标准处理就能覆盖绝大多数设备。6. 扩展从 RDS 到微型电台项目的几个方向6.1 定时校时与 RT 滚动RDS 不仅能传电台名和文本还能传时间。4A 组携带时间和日期信息接收端可以根据 4A 组自动校准时钟。如果你的项目已经在做校园广播或者小范围信息播报不妨在发射端周期性发送 4A 组接收端每收到一组就把本地 RTC 校一次。这样接收端可以脱离互联网获得比较可靠的时间源虽然不如 GPS 精确但广播覆盖范围内足够用。前提是你的发送端必须有一个相对准确的时间源比如 GPS 模块或 NTP 对时后的 ESP32。RadioText 滚动字条也很适合做信息发布。比如在商场、展厅、仓库里架一个小功率 FM 发射器用电脑上位机往串口下发一条最多 64 个字符的通知接收端收音机就能在屏幕上一行行滚动显示。这种应用不依赖 Wi-Fi 和蓝牙接收设备就是最普通的带 RDS 显示的收音机部署门槛极低。很多开源项目里已经实现了“串口读一行文字自动拆分成 2A 组发送”的功能你可以直接参考。6.2 结合 ESP32 的联网文本更新我自己的一个做法是让 ESP32 上网拉取天气信息或者排队叫号信息然后通过 I2C 控制 SI4711 把文本转换成 RDS 广播。ESP32 负责处理 HTTP 请求、解析 JSONSI4711 专心做射频调制。因为 RDS 文本本身只有 64 字节更新频率不用太高每秒更新一次就够。而且 SI47xx 的默认 Tune 操作不复杂ESP32 的小内存跑起来也没有压力。如果你把 SI4730 也接到同一个 ESP32 上还能组成一个软件定义的 FM 收发测试平台。发射端发 PS接收端解 PS通过串口打印出来这样在没有频谱仪和 RDS 分析仪的情况下也能验证整个链路是否正常。我第一次跑通这个闭环的时候感觉比做一整套协议栈还要兴奋因为它用最少的硬件验证了从数据到射频再到解析的完整通道。6.3 天线与合规提醒做 RDS 发射项目时天线和功率始终要放在脑子里。SI4711 的输出功率很小一般在几毫瓦到十几毫瓦级别但加上合适的天线后覆盖范围也能达到几十米到百米。这个功率等级适合做实验和短距离定点广播但绝对不要为了追求覆盖范围去外接功放也不要在未授权频点上长期大功率发射。合规的红线是任何发射实验都要在允许的频段、允许的功率范围内进行建议使用专用的实验频点并确保不会对其他设备造成有害干扰。这是玩无线电的基本素养也是对周围环境负责。接收端就自由得多SI4730 接收 RDS 不需要任何授权你可以放心地把它用在收音机、小屏幕歌词显示、博物馆导览等设备里。配合一个精致的点阵屏或段码屏代码量不大但成品感很强。说实话SI47xx 最吸引我的地方不是它的射频性能有多强而是它把 RDS 从一个复杂的通信协议简化成了“填属性、读属性”的普通嵌入式外设操作。你不需要真正懂傅里叶变换和锁相环也能在一天之内做出一个带文字播报的 FM 电台。如果你手上已经有一块 SI4711 和 SI4730 的测试板不妨跟着上面的流程走一遍把 PS 和 RadioText 都跑通。等看到收音机屏幕上出现自己发出去的那行字时你会觉得之前翻的所有数据手册都值了。本文还有配套的精品资源点击获取