尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

基于LDPC编码与QPSK调制的通信系统设计及FFT频偏估计仿真

基于LDPC编码与QPSK调制的通信系统设计及FFT频偏估计仿真 简介无线通信系统的物理层设计离不开调制解调、信道编码与同步技术的协同配合。数字通信中QPSK调制以恒定包络和良好的频谱效率成为经典选择而LDPC信道编码凭借接近香农极限的纠错能力为高速可靠传输提供了保障。实际收发链路中收发端晶振偏差与多普勒效应会引入载波频偏导致星座图旋转、解调性能急剧恶化FFT频偏估计作为一种数据辅助的载波同步方案通过训练序列的频谱峰值检测实现高效补偿。理解这些技术的原理与工程实现是构建完整仿真链路、评估系统误码率性能的关键。本文从通信链路总体架构出发详细剖析QPSK映射、LDPC译码以及FFT频偏估计的协同工作原理并讨论帧结构设计、匹配滤波、残余相位跟踪等工程实践要点为无线通信基带算法研究与仿真验证提供系统参考。1. 通信链路搭建思路与总体方案选型做无线通信物理层仿真绕不开“发送端怎么把比特变成信号接收端怎么把它捞回来还要在噪声环境下把误码率压下去”这条主线。这套基于QPSK调制解调、LDPC信道编译码、FFT频偏估计的同步通信系统本质上就是一条典型的数字通信收发链路信源比特从LDPC编码器出来经过QPSK映射变成复数符号插入训练序列后形成成帧数据再通过发射滤波器成型、上变频接收端做下变频、匹配滤波、粗同步、频偏估计与补偿、QPSK解调、LDPC译码最后对比收发比特统计误码率。这套架构最大的价值是把三个经常被分开讲的技术点串在了一起。很多教材讲QPSK只讲星座映射和判决讲LDPC只讲译码算法本身讲FFT只讲频谱分析但真实通信系统里它们是要协同工作的QPSK提供频谱效率LDPC提供接近香农限的纠错能力FFT用来对付收发两端晶振不理想导致的载波频率偏差。把这三者放在同一个仿真链路里用误码率曲线去评估整体性能比单独看任何一个模块都有意义得多。从方案选型的角度看选择QPSK而不是更高阶的16QAM、64QAM主要考虑两点一是QPSK的误码率理论曲线好算跟仿真结果对比时能快速验证链路正确性二是QPSK对相位噪声和频偏的容忍度相对较高做频偏估计实验时观察窗口更大不容易出现“频偏一上来就彻底解调失败”的一刀切现象。LDPC选择置信传播译码是主流做法性能好实现复杂度在MATLAB里完全可接受。FFT频偏估计属于数据辅助估计的典型方案利用训练序列的周期重复特性在频域上直接找谱峰位置算法直观、运算量小非常适合作为课程设计或者通信原理进阶实验的切入点。整套仿真结构可以分成四个层次信源信道层、编码调制层、频偏估计补偿层、误码率统计层。层次之间用标准接口连接方便单独调试各模块。比如只验证LDPC性能时可以跳过频偏模块直接用无频偏的高斯白噪声信道只验证FFT频偏估计精度时可以把LDPC部分旁路掉直接用QPSK符号做估计。这种模块化设计在实际调试中特别省时间我相信你做完之后也会有同样的体会。2. 发送端设计LDPC编码与QPSK映射的配合2.1 LDPC编码参数选择与校验矩阵构造LDPC码是线性分组码的一种核心思想是用稀疏校验矩阵描述码字之间的约束关系。所谓“稀疏”指的是校验矩阵里1的个数远小于0的个数这个特性让译码可以用迭代消息传递的方式实现并且性能逼近香农极限。在实际仿真中第一步要确定码率和码长。最常见的选择是码率1/2、码长64800或者16200这来自DVB-S2标准但自己做仿真时可以灵活处理。我建议初学阶段用码长1000到4000之间的中等码长原因很现实码长太短性能不够好画出来的误码率曲线没有“瀑布区”效果码长太长置信传播译码的迭代次数上去了MATLAB跑一次仿真要等很久调参数时会非常痛苦。校验矩阵构造有两种常用方式随机稀疏矩阵和结构化矩阵。随机稀疏矩阵生成简单直接用rand产生随机位置再稀疏化即可但要注意避免出现长度为4的环也就是校验矩阵中任意两行两列交叉位置不能同时为1否则译码性能会明显下降。结构化矩阵可以用准循环LDPC构造方式每个子块是循环移位单位阵这种矩阵译码收敛快硬件实现也友好。MATLAB里构造准循环LDPC的方式是把基础矩阵扩展基础矩阵每个元素表示循环移位位数-1表示全零子块。如果你不想手写构造过程MATLAB通信工具箱也提供了ldpcQuasiCyclicMatrix、ldpcEncoderConfig这些现成函数能直接生成符合5G NR标准的LDPC配置。不过我个人的建议是课程设计阶段还是要手写一遍编码流程哪怕是用最笨的mod(H * x, 2)方式做编码验证也能帮助你理解生成矩阵和校验矩阵之间的关系。直接调用现成函数虽然快但做完之后心里的理解深度完全不一样。2.2 QPSK映射与格雷编码的细节QPSK调制的作用是把两个比特映射成一个复数符号四个星座点分布在单位圆上幅度恒定相位分别为45度、135度、225度、315度。这种等幅度特性让QPSK对幅度衰落不敏感在AWGN信道下性能很好。映射方式上必须用格雷编码也就是相邻星座点之间只差一个比特。这样做的意义在于当噪声导致符号被判到相邻星座点时只会造成一个比特错误而不是两个比特同时错。理论误码率公式里格雷编码QPSK的误比特率大约等于误符号率的一半这个关系只有格雷编码下才成立。如果映射方式随意乱写仿真结果会比理论值差大约2倍而且你自己还很难发现是映射的问题。MATLAB里实现QPSK映射可以直接用qammod(data, 4, gray)注意这里的4对应QPSK也可以手写映射表% 输入比特流data_bit为列向量长度偶数 % 每两个比特映射为一个QPSK符号 data_qpsk zeros(length(data_bit)/2, 1); for k 1:length(data_bit)/2 b0 data_bit(2*k-1); b1 data_bit(2*k); if b00 b10 data_qpsk(k) exp(1j*pi/4); elseif b00 b11 data_qpsk(k) exp(1j*3*pi/4); elseif b01 b11 data_qpsk(k) exp(1j*5*pi/4); else data_qpsk(k) exp(1j*7*pi/4); end end这段代码需要确保星座图是格雷映射顺序我这里是按00、01、11、10的顺序对应相位递增这样相邻符号只差1比特。LDPC编码器和QPSK映射之间需要衔接的一个细节是交织。LDPC译码时突发错误会导致局部校验约束失效如果突发错误正好落在同一组校验节点约束的变量节点上译码会非常吃力。加入一个随机交织器把编码后的比特顺序打乱能让突发错误在时间上扩散开译码性能会稳定不少。交织器用randperm生成索引就行接收端逆序还原代码量很小但对LDPC在衰落信道下的性能有实际帮助。当然在纯AWGN信道下交织的增益不明显不过留着它可以让链路更接近真实系统。2.3 帧结构与训练序列设计发端数据不能把编码比特直接丢进信道要按帧格式打包。帧结构里除了数据符号还要有训练序列和导频符号。这套系统里训练序列承担两个任务一是帮助接收端做帧同步确定符号从哪里开始二是为FFT频偏估计提供已知数据。训练序列我建议用恒包络零自相关序列也就是CAZAC序列或者是简单的PN序列。CAZAC序列有很好的自相关特性峰值尖锐、旁瓣低用来自相关做帧同步非常可靠。Zadoff-Chu序列是CAZAC序列的一种生成方式很简单% Zadoff-Chu序列生成长度为N根索引为u n (0:N-1).; zc_seq exp(-1j * pi * u * n .* (n1) / N);训练序列长度取64或者128都行太短则频偏估计分辨率不够FFT的点数不够导致估计误差大太长则频谱效率低。我做仿真时习惯用64个符号的训练序列后面接几个符号的静默间隔再接数据符号块这样接收端用训练序列做完估计后还能有一段缓冲来处理补偿。帧结构还有一个容易被忽略的点相位连续性。QPSK符号在帧边界切换时不要突然跳变幅度成型滤波器的记忆效应会让幅度跳变产生频谱扩展。虽然仿真里不直接影响误码率但如果后面要加功放模型或者频谱模板约束这个问题就会暴露出来。好在QPSK本身是恒包络调制只要成型滤波器设计得当这个问题一般不会太严重。3. 接收端核心同步、频偏估计与补偿机制3.1 为什么必须做频偏估计发射机和接收机各自使用独立的晶振产生载波两个晶振的频率不可能完全一致即使标称频率都是2.4GHz实际偏差可能达到几十甚至几百赫兹。除此之外移动通信场景下多普勒频移也会给接收信号叠加额外的频率偏移。频偏对QPSK解调的影响是毁灭性的解调时信号经过本振混频后会残留一个随时间累积的相位旋转项符号逐渐旋转星座图看起来就像一个不断转动的圆环最后判决器根本没法工作。频偏大小用归一化频偏来描述最方便也就是频偏与符号速率的比值。QPSK符号速率如果是1Msps归一化频偏0.01意思就是实际频偏10kHz。归一化频偏超过0.1之后QPSK星座会在一两个符号周期内就旋转大半圈不做估计补偿基本不可能正确解调。FFT频偏估计方法在归一化频偏小于0.5时都能正常工作这是由FFT离散频谱间隔决定的限制实际系统中一般能满足。3.2 FFT频偏估计算法原理与实现FFT频偏估计的基本原理是发送已知的训练序列接收端收到训练序列后用本地存着的原始训练序列做共轭相乘。如果没有频偏相乘结果的相位是固定的如果有频偏相位会随时间线性变化。把相乘结果看成一个单频复正弦信号它的频率就等于频偏大小。对这个复信号做FFT找到谱峰位置就能反推出频偏。数学表达上接收信号可以表示为r(n) s(n) * exp(j*2*pi*f_offset*n*T_s) w(n)其中s(n)是原始发送符号T_s是符号周期w(n)是高斯白噪声。本地存有s(n)所以计算z(n) r(n) * conj(s(n)) |s(n)|^2 * exp(j*2*pi*f_offset*n*T_s) w(n)z(n)就是一个频率为f_offset的复正弦加噪声。对z(n)做N点FFT得到频谱X(k)谱峰位置k_peak对应的数字频率就是f_digital k_peak / N换算成实际频偏f_offset_est k_peak / (N * T_s)实现代码大致如下% r_seq为接收训练序列s_seq为本地训练序列 z r_seq .* conj(s_seq); Nfft 256; X fft(z, Nfft); [~, k_peak] max(abs(X)); if k_peak Nfft/2 k_peak k_peak - Nfft; end f_est k_peak / (Nfft * T_s);这里有个使用细节要提醒k_peak是单边索引如果谱峰出现在FFT后半段说明负频率需要减去Nfft做修正。同时如果频偏恰好落在两个FFT频点正中间会造成FFT泄漏谱峰位置可能会偏一格估计误差达到一个FFT分辨率。解决措施是先用FFT粗估计再用抛物线插值对峰值位置做细化也就是在峰值附近取三个点拟合二次曲线得到子频点精度的峰值位置。这个细化操作能把频偏估计精度提升一到两个数量级。3.3 频偏补偿与残余相位跟踪估计出频偏之后补偿方式是用一个数字控制振荡器生成反向频率的复指数序列把接收信号乘上去n (0:length(rx_sym)-1).; comp_seq exp(-1j * 2 * pi * f_est * n * T_s); rx_comp rx_sym .* comp_seq;补偿后理论上频偏被完全抵消但实际估计值有误差残余频偏仍然存在只是很小。残余频偏会导致星座图还有非常缓慢的旋转一次仿真几百上千个符号时可能看不出明显问题但如果帧很长也需要在数据段插入导频做残余相位跟踪。实现方式常见有两种一种是判决辅助法把解调后的符号硬判决后与接收符号比较相位差再用环路滤波平滑另一种是每帧里插入少量导频符号插值估计数据段相位偏移。我个人偏好后一种实现简单稳定可靠代价是少量频谱开销。导频间隔可以根据残余频偏大小调整残余频偏小、符号速率高导频可以稀疏一点。3.4 定时同步与匹配滤波的配合做频偏估计之前接收端先要做定时同步。符号定时偏差同样会让星座图发散不过它跟频偏的后果不太一样频偏让星座点整体旋转定时偏差让星座点向两侧扩散像一团糊掉的云团。定时同步通常用早迟门或者Gardner算法实现这两者都是非数据辅助的定时恢复方法可以在没有训练序列的情况下工作实现也不复杂。MATLAB通信工具箱中有symeol等函数可以完成定时同步但自己手写一遍会更有感觉。匹配滤波器的设计也要跟上。发射端用了升余弦成型滤波器来限带接收端必须用匹配的根升余弦滤波器来最大化信噪比。发射和接收滤波器的滚降系数要一样通常是0.22或者0.35。两者级联后的效果等于一个升余弦滤波器满足奈奎斯特第一准则也就是在理想采样时刻没有符号间干扰。如果你在仿真里把成型滤波器省略了误码率曲线会非常接近理论值但那样不够真实。加了成型滤波器和匹配滤波器之后接收端需要对采样点进行精确控制否则采样时刻偏移会引入额外的符号间干扰。这也是定时同步模块存在的必要性。4. LDPC译码实现与误码率性能分析4.1 置信传播译码算法剖析LDPC译码常用的算法是置信传播也叫和积算法。核心思想是因子图上的消息迭代变量节点和校验节点互相传递置信度信息通过若干次迭代收敛到最终判决结果。每个校验节点代表一个校验方程每个变量节点代表一个码字比特。迭代过程分两步第一步变量节点把外部信息传递给相连的校验节点信息内容是该比特为0或1的概率但要用对数似然比表示方便加减运算第二步校验节点根据该校验方程约束把所有外部信息综合起来反过来更新变量节点的置信度。对数似然比定义为L ln(P(b0) / P(b1))信道输出的软信息作为初始LLR输入当信道为AWGN时BPSK/QPSK解调后的LLR可以近似为L_init 2 * y / sigma^2y是匹配滤波后的接收符号实部或虚部sigma^2是噪声方差。这个初始化看着简单但在实际仿真里很容易出错的一个点就是噪声方差估计。如果你用awgn函数加噪得到的是符号信噪比EbN0下的噪声功率计算时要转换成噪声方差否则LLR初始化会系统性偏大或偏小译码性能大打折扣。置信传播译码的迭代次数一般取5到50之间越多性能越好但边际收益递减。实际系统常用归一化最小和算法替代标准置信传播减少计算量而性能损失很小。归一化最小和的更新公式比和积简单只需要比较和相加不用求双曲正切这类复杂函数。MATLAB仿真中标准置信传播速度勉强可以接受但如果你要跑多个信噪比点建议用最小和算法省时间见效快。4.2 迭代译码停止准则与最大迭代次数译码不是一定要迭代到最大次数很多时候迭代几次就已经收敛到合法码字了。可以在每次迭代结束后做一次硬判决然后乘以校验矩阵的转置判断是否满足所有校验方程如果满足就提前停止。这个策略能省下大量无效迭代时间尤其是高信噪比区几乎一两轮就能收敛。最大迭代次数设置的权衡要在仿真时间与性能之间平衡。取10次时曲线已经很接近性能极限取50次时再提升有限但仿真耗时几乎翻倍。我做整条链路仿真时习惯设20次既不会太慢又能看到明显的编码增益。4.3 误码率统计方法与仿真结果解读误码率统计时要将译码输出比特与发端原始信息比特做对比。注意这里对比的应该是LDPC编码前的信息比特而不是编码后的码字比特因为信息比特才代表真实传输的数据。LDPC译码输出的就是信息位的软判决结果通过message decoded_cw(1:K)提取前K个比特即可。蒙特卡洛仿真至少要在每个信噪比点跑足够多的帧数统计出的误码率才有意义。一般要求统计到的错误比特数至少达到100个否则置信区间太宽。低信噪比区错误比特多跑几百帧就够高信噪比区几乎没错可能几千帧都统计不到100个错误比特这时可以适当降低帧数要求或者停止条件设置成“达到最大帧数就结束”。典型结果会是这样的趋势未编码QPSK的误码率曲线沿着理论值走在误码率10^-3处对应的信噪比大约是9.8dB加了LDPC编码后同样的误码率只需要大约2到3dB左右的信噪比这就是编码增益。编码增益的大小取决于码率、码长、迭代次数码率越低增益越大。1/2码率LDPC在AWGN信道下相比未编码QPSK能获得大约6到8dB的增益对应10^-5误码率这是非常可观的。仿真中常见的一个误判是LDPC性能出现错误平层也就是误码率曲线在高信噪比下不再下降变成一条水平线。原因通常是短环太多导致译码陷入局部最优或者量化比特数太少。解决方案是检查校验矩阵最小环长或改用准循环LDPC矩阵。5. 完整仿真流程从参数设置到结果可视化5.1 仿真参数表与主程序结构我习惯把仿真参数集中放在脚本开头统一修改避免到处找参数。核心参数如下参数名称数值/取值说明符号速率 Rs1e6 Hz决定频偏归一化基准调制方式QPSK2比特/符号LDPC码率1/2编码器吞吐量LDPC码长 N2016中等码长仿真速度与性能均衡训练序列长度64用于帧同步与频偏估计归一化频偏0.05相当于50kHz1MHz符号速率信噪比范围0:2:12 dBEbN0观察瀑布区FFT点数256频偏估计分辨率最大译码迭代次数20置信传播译码主程序流程就是发端、信道、收端三段的串接每跑完一个信噪比点统计一次误码率。为了方便看不同模块的作用我建议设置一个enable_ffo开关和enable_ldpc开关这样能分别运行“无频偏有编码”、“有频偏无编码”、“有频偏有编码”三种组合一次性画出多条曲线对比报告里能用到的素材就有了。5.2 频偏估计精度直观验证方法频偏估计模块好不好用不能光看最终误码率因为误码率还受其他模块影响。单独验证频偏估计时可以在无噪声环境下设置已知频偏跑一次估计记录估计值与真实值的差。多测几组不同频偏值画一条“估计频偏-真实频偏”曲线理想情况下是过原点的45度直线。这样能直观看到估计范围边界在哪里、偏差有多大。我还喜欢观察估计后的星座图。补偿前星座点画出来是一个旋转的圆环补偿后应该收敛成清晰的四个聚类点。波形上也能验证取训练序列段的相位差分正常情况下相位差应该是恒定值有频偏时相位差随时间线性增加补偿后这个线性趋势消失。这些可视化手段调试时非常有用。5.3 程序操作视频与代码注释说明仿真代码一定要写清楚注释这不仅是为了别人能看懂也是为了自己两周后回来看还能看懂。我的做法是每个函数头部写清输入输出参数、功能描述、调用示例关键算法段落在旁边用中文注释说明数学原理中间变量命名做到自解释比如rx_ffo_compensated一眼就知道是频偏补偿后的接收信号。代码里可以加fprintf在关键节点打印进度比如每个信噪比点跑完后打印当前误码率这样长时间仿真时你能看到进度不会心里没底。更正式的做法是用waitbar做一个进度条但会稍微拖慢速度仿真量不大时无所谓。操作视频方面核心是录制整个仿真运行的完整过程包括参数修改、脚本运行、结果图生成这三个环节。演示时不要剪切让观看者看到真实的运行等待时间反而更有说服力录制时画面要清晰命令行打印的信息要能看到图形窗口的坐标轴和标题要清楚可读。如果需要节省时长可以倍速播放等待过程但倍速切换的地方用字幕提示一下。6. 常见问题排查与调试经验分享6.1 星座图发散不收敛的排查思路如果频偏补偿之后星座图依然是一个环或者一团糊先不要怀疑算法本身按以下顺序排查第一检查频偏估计的符号序列是否对齐。接收端取训练序列时如果起始位置偏了几个符号共轭相乘的结果完全不正确频谱里根本看不到尖锐谱峰。可以用自相关峰值先确认帧头位置再取训练序列。第二检查频偏符号方向。补偿时忘记取负号相当于把频偏放大了一倍。第三检查归一化频偏单位是否一致。符号速率和频偏的单位要匹配如果符号速率是1MHz频偏却用Hz算出来的归一化频偏会差六个数位。这几种情况我全都踩过。尤其是第一个符号对齐问题在块仿真里特别容易出错因为接收端处理的是整帧数据取序列时索引稍有偏移就很隐蔽。6.2 LDPC译码性能与理论偏差大的原因LDPC译码性能不好可以优先怀疑以下几个因素。校验矩阵存在短环是最负面影响之一构造随机矩阵时一定要做环长检测。其次是LLR初始化不正确主要是噪声方差估计不准。我建议在代码里单独输出信道噪声功率的统计值与理论值对比确认无误再继续。第三是最大迭代次数太少少于5次时编码增益几乎体现不出来。最后是QPSK软解调时忘记把实部和虚部当成两个独立BPSK通道分别计算LLR导致软信息只有一半性能直接损失约3dB。6.3 仿真速度优化的几个实用技巧LDPC译码是整条链路最慢的环节加速方法主要有三种。用归一化最小和代替标准置信传播计算速度提升非常明显。用MATLAB的coder.extrinsic或者给循环加预分配避免变量动态扩展拖慢速度。如果条件允许可以用parfor对多个信噪比点并行仿真这个在控制CPU核数后加速比接近线性。另外一个容易被忽视的性能瓶颈是FFT点数。频偏估计只需要256点FFT就够如果你写成4096点速度会慢很多精度提升也有限。训练序列长度固定的情况下FFT点数不是越多越好点到一定程度后分辨率已经优于频偏估计需求再增大只是浪费计算资源。6.4 误码率曲线不平滑的统计问题蒙特卡洛仿真误码率曲线在高信噪比区抖动是正常的因为错误比特数太少统计相对误差大。处理办法有两种一是增加帧数让统计到的错误比特数达到目标值二是对曲线做平滑处理但报告里最好同时给出原始点和平滑线别把真实统计信息藏掉。我通常会设置一个错误比特数阈值比如min_errors 100只有当当前信噪比点累计错误比特数超过100或者帧数达到上限时才停止这样得到的曲线又平滑又真实。7. 仿真结果分析与性能评估视角整条链路做完后建议从三个维度评估系统性能。第一频偏估计精度对系统性能的影响。固定信噪比分别设置归一化频偏为0、0.01、0.05、0.1观察误码率变化。频偏在0.01以内时经过估计补偿后误码率应该与无频偏时基本一致频偏超过0.1时即使补偿残余误差也会带来轻微性能损失。第二LDPC编码增益的验证。对比“无编码QPSK”和“LDPC编码QPSK”的误码率曲线在10^-4误码率处读取信噪比差这就是编码增益。第三不同LDPC码长对性能的影响。码长从1000增加到4000性能会有明显提升但仿真时间也增加这个权衡在工程上是真实存在的。我个人的体会是这套系统做完之后你对“通信链路中各模块怎么衔接”的理解会比单看每一部分深刻得多。尤其是当你自己动手改参数、观察星座图变化、排查各种匪夷所思的bug之后再回头去看课本上的公式会突然觉得它们都活了过来。最后再分享一个小技巧所有模块先单独测通再级联级联时用无噪声通道跑通整条链路再逐步加噪声和频偏这样能帮你把复杂系统的调试复杂度降一个量级。p a hrefhttps://download.csdn.net/download/ccsss22/91633575 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p
返回列表