GNURadio 实现FM RDS收发仿真以及使用HackRf one发射FM RDS信号
近一年来我在做汽车收音系统,一直在跟 FM 模块打交道,但有个问题特别头疼:国内几乎找不到能用的 RDS 信号源。
我们车机支持完整的 RDS 功能——能显示电台名(PS)、滚动文本(RT)、自动切换区域(AF)等等。可市面上那些的FM 信号发生器,大多数只输出一个单音或音频载波,根本没有 RDS 子载波。收音机能响,但 RDS 解码器永远是空的。正好在我手头有台 HackRF One,干脆从零搭一个带 RDS 的 FM 发射源方便测试也能让自己更深入的理解FM的调制解调原理。
FM 广播不是你想的那么简单
很多人以为 FM 就是把音频直接调频发射出去。其实标准 FM 广播的基带信号是个“拼盘”:
- 0–15 kHz:主信道,放 L+R(兼容单声道)
- 19 kHz:一个很弱的导频音(pilot tone),接收端靠它再生 38 kHz 副载波
- 23–53 kHz:L−R 差信号,用 38 kHz DSB-SC 调制,实现立体声
- 57 kHz:RDS 数据通道,BPSK 调制,速率 1187.5 bps
这些信号全部加在一起,才构成真正的“复合基带”,再送去 FM 调制。漏掉任何一块,接收端要么没立体声,要么 RDS 解不出来。

RDS 是怎么塞进去的?
RDS 数据结构其实挺讲究。每 104 比特为一块(含 16 位纠错码),以固定格式传输 PS、PTY、RT 等字段。关键点在于:
- 载波频率必须是 57 kHz(正好是 19 kHz 导频的整数倍,方便锁相)
- 调制方式是 BPSK,但要先做差分编码
- 波形得经过成形滤波(通常是根升余弦),避免频谱溢出
我在 GNU Radio 里用 gr-rds 提供的 rds_encoder 模块生成数据流,后面接了差分编码器、脉冲整形、正交调制到 57 kHz。再和音频路径合成,最后进 FM 调制器。
特别要提醒的是:RDS 数据流的码率(1187.5 bps)必须和主音频路径的采样率严格对齐。GNU Radio 里如果音频用的是 380 kHz 采样,那 RDS 路径也得插值/抽取到同样的时钟域下。否则哪怕数据内容完全正确,接收端也会因为采样偏移导致位同步失败——表现就是 PS 闪烁、RT 丢字,甚至完全解不出 RDS。我一开始没注意这点,以为是编码错了,结果折腾半天才发现是采样率没对齐。
我的GNU Radio工程已经开源到了我的Github:https://github.com/Jubian540/GnuRadio-FM-RDS/tree/main
实现了一个不依赖任何硬件的RDS发送和接收的仿真,只需要把频率调制节点输入到HackRF即可输出可用的FM-RDS信号。

更多推荐
所有评论(0)