ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

从bit流到QPSK点簇——基于P201Pro和GNU Radio的SDR收发系统

从bit流到QPSK点簇——基于P201Pro和GNU Radio的SDR收发系统 软件无线电实验4阶段性总结从bit流到QPSK点簇——基于P201Pro和GNU Radio的简单收发系统软件无线电这名字听起来高大上实际做起来就是一句话把无线的活儿搬到电脑里干。这次实验我用P201Pro这块基于AD9361的SDR板子配合GNU Radio搭了一套最简单的QPSK收发链路完整走了一遍从bit流到星座点簇的流程。整个过程不复杂——信号源产生原始比特、串并转换、QPSK映射、脉冲成形、上变频发射接收端再一路解调回来。但当屏幕上的接收星座图从一片旋转的模糊圆弧慢慢收敛成四个分明的点簇时那种“链路通了”的成就感确实很真实。这套配置适合谁如果你是刚接触SDR的学生想搞明白调制解调的全流程或者你是做通信原型验证的工程师需要一个成本低、上手快的验证平台——这套组合都值得参考。它能帮你建立从数字域到射频域的完整映射关系GNU Radio的图形化编程让中间信号可以逐级可视化排查问题比纯代码环境直观得多。这篇总结我把完整链路拆开讲包含模块参数、调试过程和踩过的坑照着搭就能跑通。1. 实验目标与整体设计思路1.1 这次实验到底打通了什么实验核心是搭一条完整的“bit进、bit出”的QPSK收发链路。所谓完整指的是信源端产生一串0/1原始比特经过符号映射变成IQ数据在数字域完成脉冲成形后交给AD9361的DAC上变频到射频通过天线发出去接收端再经过AD9361的ADC下变频回到数字IQ在GNU Radio里完成匹配滤波、定时同步、载波恢复、判决解调最终重新变回bit流。很多人做SDR实验时喜欢直接用现成的OFDM发射模块或者某个封装好的解调模块拖几个块连起来就跑通了。但那个过程中很多中间状态是个黑盒。这次实验的意义在于把每一个中间环节全部可视化比特流的帧格式、符号映射表、星座图的旋转过程、I/Q两路的波形、眼图睁开的过程每个环节都能在示波器和星座图上找到对应现象。对于做通信验证的工程师来说这种“逐级点亮”的调试方法比直接堆模块有用得多——出问题时你能准确判断是调制的问题、信道的问题还是同步的问题。整条链路的信号流是字节流 → 2bit分组 → 符号映射 → RRC脉冲成形 → AD9361上变频 → 天线 → 空间传播 → 天线 → AD9361下变频 → RRC匹配滤波 → 定时同步 → 载波恢复 → 星座点判决 → 比特流还原。每一步我都在流程图里加了探针方便随时看中间信号长什么样。1.2 为什么选P201Pro搭配GNU RadioP201Pro是搭载AD9361收发器的软件定义无线电开发板。AD9361覆盖70MHz到6GHz频段带宽从200kHz到56MHz可调覆盖了绝大多数民用通信实验场景。这块芯片的特点是收发链路完全可配置增益、滤波器、采样率都可以通过寄存器控制而GNU Radio里有官方的libiio驱动支持不需要自己写底层寄存器操作代码。GNU Radio这套方案有几个实际优点。第一图形化流程图的调试成本非常低改一个参数、拖一个探针就能立刻看到波形变化这对教学和原型验证特别友好。第二社区生态成熟星座图显示、Costas环、Symbol Sync这类模块都是现成的出问题时可以顺着模块源码往下追不会卡在“找不到问题在哪”。第三是Python嵌入的便利性——导入P201Pro的源/汇模块只需要配置采样率、中心频率、增益几个参数全是GUI下拉菜单新手也能快速上手。可能有人会问为什么不用FPGA加Vivado的方案去跑这个实验。说实话我也试过光是AXI总线和DMA的调试就要耗掉一周对验证通信算法来说投入产出比太低。USRP当然性能更好但价格高一个数量级。P201Pro这种几百块钱级别的板卡刚好卡在教学验证的甜点上性能和可玩性平衡得不错。2. 从bit流到QPSK点簇链路原理2.1 比特流怎么变成符号QPSK正交相移键控的本质就是一次处理两个比特把它们映射成复平面上的四个点。比特流按2bit一组切分按照Gray编码映射输入比特映射值归一化相位000.707 j0.70745°01-0.707 j0.707135°11-0.707 - j0.707225°100.707 - j0.707315°这个映射表看起来简单但决定了I路和Q路各自承载的信息。用生活里的类比两个开关的灯管可以组合成四种状态两个bit经过QPSK调制后一个符号就携带2比特信息。如果符号率是1Msps有效比特率就是2Mbps。实验里我把符号率设为1Msps方便观察和计算。在GNU Radio里这一步通常用Chunks to Symbols模块实现把0/1映射到指定的符号表。也可以用Constellation Modulator这个更上层的封装但我在实验中坚持用Chunks to Symbols因为符号表可以直接填成列表调试映射关系时一眼就能看清楚出问题时不用拆封装。映射之后的输出是复数流实部对应I路虚部对应Q路这正是后面AD9361需要的IQ数据格式。如果直接把IQ数据不经过任何处理就发射频谱会有很大的旁瓣因为矩形脉冲的频谱是sinc函数形状衰减非常慢。这就会干扰邻道信道也无法通过带限信道传输。所以接下来必须要做脉冲成形。2.2 脉冲成形让信号在带宽内乖乖听话随机序列经过QPSK映射后如果直接用方波脉冲承载频谱会向外蔓延。解决办法是加根升余弦滤波器RRC在发送端和接收端各放一个两者级联等效为升余弦滤波器满足奈奎斯特第一准则无码间串扰。RRC滤波器有个关键参数——滚降系数alpha它决定了带宽占用和符号间干扰的折中。alpha越小频谱越紧凑但对定时误差越敏感alpha越大波形越“胖”频谱浪费越多但同步更稳健。0.35是我实验中固定的取值这个数值是工程里的通用选择兼顾频谱效率和同步性能。计算占用带宽的公式是BW (1 alpha) × Rs所以alpha0.35、Rs1Msps时信号占用带宽约1.35MHzAD9361的RF带宽我设置成2MHz就足够容纳。采样率和符号率的关系也要算清楚。我把采样率设置为8Msps也就是8倍过采样。每个符号在数字域里被8个采样点描述点数越多波形越平滑但计算量和数据量也成正比。8倍是GNU Radio里Symbol Sync模块比较推荐的范围——太低眼图会发毛太高数据量暴增却没额外收益。这里有个容易忽略的点GNU Radio里的RRC滤波器参数除了alpha还有Number of Taps抽头数和Samples per Symbol每符号采样数。抽头数太少会让滤波器频响与理论值偏离太多又增加计算量。项目里我设为45个抽头在实际中已经足够平滑。如果发现滤波后的信号在频谱上有奇怪的纹波可以先检查抽头数是不是太小了。2.3 QPSK点簇的形成与旋转问题的根源星座图上看到的那四个点簇本质是接收端把射频信号搬回基带之后对每个符号的I/Q幅度取样的结果。理想情况是收敛成四个点但实际你会看到点簇旋转、发散、甚至呈环形。这里面最核心的两个原因是载波频偏和定时误差。载波频偏让星座图整体旋转。收发两端本振频率只要有几百赫兹偏差符号持续时间一长相位就会累积偏移四个点就变成四条圆弧。GNU Radio解决这个问题有专门的Costas环模块它的环路带宽直接影响收敛速度和噪声性能。定时误差则让采样点落在符号能量扩散的位置点簇看起来就像炸开的棉花糖。实验中我最推荐观察的就是这个环节。把Costas环的环路带宽从0.01调到0.1星座图从缓慢旋转慢慢变成收敛你能非常直观地理解锁相环“锁定”的含义。我第一次看到这个过程时才真正理解为什么教科书上反复强调载波同步是相干解调的前提。看完现象再回来读锁相环的原理理解深度完全不一样。3. GNU Radio流程图搭建与硬件对接3.1 发射链路的模块组织发射链路我在GNU Radio里按这样的顺序组织Random Source模块产生0到255的随机字节Throttle模块限速防止CPU全速跑导致数据溢出Pack K Bits模块把字节按需要的位数切出来Chunks to Symbols模块完成QPSK映射Root Raised Cosine Filter做脉冲成形P201Pro Sink模块把基带IQ数据发给硬件发射每一步都有值得注意的坑。Random Source产生的是字节8bitPack K Bits里的K参数设为2时每个字节会被拆成4个2bit符号。这里有个容易搞混的地方映射之前的数据类型是byteChunks to Symbols的输出是complex上下游模块的数据类型不匹配时GNU Radio会直接报错但报错信息有时候很不直观看起来像是“连接失败”。遇到这类问题先检查数据类型。Throttle模块要不要保留是个问题。如果接收端也是软件处理保留Throttle可以避免CPU满负荷运行但如果接收端是真实硬件硬件本身已经限制了数据速率Throttle反而可能引发数据不连续甚至丢包。我的做法是仿真模式保留Throttle硬件模式直接去掉或者注释掉。P201Pro Sink里几个参数值得单独说。Sample Rate设成8MCenter Frequency我选在2.45GHz但如果你周围Wi-Fi环境比较密集2.45GHz正好落在Wi-Fi频段内建议改到2.42GHz左右避开干扰。RF Bandwidth根据符号率设置成2MHz。发射增益默认是0dB——这个值基本等于没发射近距离无遮挡时0dB够用隔一堵墙至少需要10dB以上。3.2 接收链路从天线到点簇接收端的模块顺序P201Pro Source接收射频信号Root Raised Cosine Filter做匹配滤波Symbol Sync定时同步恢复最佳采样时刻Costas Loop载波恢复Constellation Sink显示星座点簇看起来只有5个模块门道不少。Symbol Sync模块我建议先用默认的Gardner算法它不需要额外的前导序列适合连续数据流。Loop Bandwidth参数控制定时收敛速度过大会引入噪声过小跟不上频率漂移实测0.01到0.03之间比较稳。Costas Loop要注意Order参数。QPSK解调必须用4阶Costas环因为QPSK信号的相位有4个收敛点。我一开始误用了2阶结果星座图分成两簇且不断跳动因为BPSK的收敛模式根本不满足QPSK的需求。这个错误在仿真阶段就能发现所以强烈建议先做纯软件仿真验证再上硬件能省去大量排查时间。Constellation Sink显示的是每个符号采样时刻的IQ值。为了能看到清晰的点簇可以在Symbol Sync之后加一个Binary Slicer或者直接连Constellation Sink。注意如果把Constellation Sink接在Symbol Sync之前看到的是所有过采样点点簇边缘会拖尾这不是问题是显示位置不对。3.3 P201Pro硬件参数与AD9361对接要点P201Pro在GNU Radio里被识别为通用的iio设备。使用前先确认固件版本和libiio驱动版本命令行用iio_info -s能看到设备列表。如果设备没出现在列表里大概率是USB连接问题——尽量用短的、带磁环的USB线长线供电不足会让设备反复掉线。AD9361配置有个容易忽略的地方发射和接收通道的采样率必须一致否则数据流会失真或丢包。另一个关键是滤波器自动配置。AD9361内部有可编程的FIR滤波器GNU Radio驱动会自动计算但前提是你在Device参数里设置的采样率不要超过芯片支持范围。增益策略上接收增益从30dB起调观察星座图信噪比。如果点簇开始合拢说明增益太高导致削波如果点簇发散明显再逐步加大。发射增益控制严格一点近距离测试时过高的发射增益反而让接收端前端饱和点簇质量不升反降。实测下来的规律是近距离几米内发射增益10dB加上接收增益40dB左右星座图的四个点簇清晰分立。4. 实测过程与结果分析4.1 完整测试流程分四步走实测流程我分成四个阶段每阶段都有独立目标避免全链路出问题时不知道从哪排查。第一阶段仿真模式验证流程图。不接P201Pro接收端直接从发射端拿数据或者加一个信道模型模块模拟噪声和频偏。确认星座图能收敛到四个点各模块逻辑正确。这个阶段纯粹验证流程图本身有没有问题。第二阶段环路自测。把P201Pro的发射和接收用一根射频线直接相连不经过天线。这样能把无线信道的干扰排除掉专注调试同步和恢复模块。这个阶段星座图应该很容易收敛点簇小而清晰。如果环路自测都收不好问题几乎肯定在软件链路里。第三阶段天线互发。两个P201Pro一个发一个收距离几米。这时候才真正考验链路性能多径、环境噪声、天线极化方向都会影响星座图质量。我测试时发现把接收天线立起来和发射天线平行时点簇最清晰垂直时发散明显这就是极化失配的影响。第四阶段参数扫描。逐个改变alpha、采样率、增益观察星座图和误码率的变化记录接收效果最好的参数组合。这一步既是优化也是理解参数意义的最佳途径。比如把滚降系数从0.35改到0.22星座图在无遮挡时差别不大但在多径稍微明显的室内0.35明显更稳。4.2 星座图观察与点簇质量评估衡量星座图质量的简单标准四个点簇清晰分立点簇半径尽量小没有旋转。我调好之后的效果是四个点簇的半径大约0.08归一化幅度这是近场无遮挡下的健康水平。但要特别注意点簇的大小不能只看整体半径。如果四个点簇虽然分立但形状不对称——比如左下方比右上方扩散得宽——那通常不是噪声问题而是I/Q不平衡。AD9361的发射和接收都有自己的I/Q校准功能如果发现这种不对称可以在硬件层面触发I/Q校准。P201Pro的驱动里有内置的校准接口重新跑一次校准流程通常能修复。记录一个有意思的现象当接收增益超过50dB时点簇反而变差。原因是接收前端进入饱和区AD9361的增益过大会压缩信号动态范围有效信噪比不升反降。调试时不要盲调增益要观察曲线的变化趋势。如果增益从40dB往上加时点簇半径几乎不变说明信号已经足够强再加就没有意义了。5. 常见问题与排查技巧实录5.1 星座图整体旋转收不住这是几乎每个人都会遇到的问题。现象是星座图像风扇一样转圈偶尔能停住几秒又开始转。根源是载波频偏Costas环捕获范围不够或环路带宽太窄。处理思路分两步。先确认频偏的绝对大小——在星座图旁边拖一个FFT Sink观察接收信号中心频率与设定中心频率的偏差。如果偏了几千赫兹说明本振偏差太大应该先修正中心频率如果只偏几百赫兹直接调大Costas环路带宽到0.05以上一般就能锁住。另一个技巧是让发射端持续发送长序列而不是帧突发。很多SDR平台在开始传输的前几百微秒有频率跳变等系统稳定了再去锁相成功的概率会大很多。实验里我用的是连续随机比特流天然满足这个条件。5.2 点簇发散或者点簇模糊点簇发散有两种常见情况。第一种是SNR过低星座图四个点簇的边缘糊在一起这种只能通过调增益、降低带宽或缩短距离解决。第二种是定时同步问题表现是点簇向径向扩散看起来一圈一圈的这时要检查Symbol Sync的参数特别是环路带宽和过采样率是否匹配。GNU Radio里的Polyphase Clock Sync和Symbol Sync都可以做定时恢复但使用条件不一样。Symbol Sync更适合符号率恒定的情况Polyphase Clock Sync在多径场景下更稳健。室内反射严重时建议换Polyphase Clock Sync并适当增加滤波器抽头数。我做过对比同样参数下室内有反射时Polyphase Clock Sync的点簇半径比Symbol Sync小约30%。5.3 数据速率不匹配或丢包P201Pro数据通过USB传输GNU Radio的采样率设置一旦超过USB实际吞吐能力就会丢包现象是星座图周期性闪断。8Msps采样率、16bit量化、I/Q双通道数据量约32MB/sUSB 3.0完全能搞定但如果采样率提到20Msps以上就要观察是否丢包。排查丢包最直接的手段是看GNU Radio界面右下角是否出现“U”标志underrun意味着队列读数据的速度跟不上。出现“U”时优先降低采样率、关闭后台进程或者把流程图里的Throttle模块去掉——硬件源本身已经限速Throttle只会添乱。如果还不行检查USB线缆质量换成屏蔽更好的短线。5.4 不同GNU Radio版本的兼容坑GNU Radio从3.7升级到3.10很多模块的参数名和默认行为都变了。Symbol Sync的默认算法、Constellation Sink的画图刷新机制、P201Pro调用的iio驱动接口在3.8和3.10之间就有明显不同。写这篇总结时我特意核对了GNU Radio 3.10的文档确认关键模块的参数名没有变化。如果你复现时星座图完全显示不出来先检查界面右侧的Queue长度和Sample Rate设置。很多时候不是链路问题而是显示缓冲区太小或刷新率太低——这是GNU Radio GUI的锅不一定代表RF链路故障。最后分享一个实用的小经验。我在反复调试中养成的习惯是每改一个参数之前先在星座图或者时域波形上截一张图存下来。这样参数扫描结束后对比截图能清楚看出哪个调整起了作用、哪个是无效操作。这套“截图对比法”在排查问题时尤其高效——凭记忆判断参数影响非常不可靠眼睛是会骗人的。从bit流到QPSK点簇这个链路本身不复杂但完整跑通之后你对软件无线电里“数字域”和“射频域”之间那条分界线的理解会比看书深刻得多。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进