ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

SC-FDE单载波频域均衡完整MATLAB仿真:UW序列、定时与载波同步实现

SC-FDE单载波频域均衡完整MATLAB仿真:UW序列、定时与载波同步实现 做通信物理层仿真的朋友应该都有这种感觉OFDM的参考代码一抓一大把但SC-FDE单载波频域均衡的完整链路反而不好找。这个项目标题我一看就觉得很对味——它把单载波频域均衡链路里最关键的几个点都点出来了UW序列、QPSK调制、定时同步、载波同步最后还要落到MATLAB仿真上。说实话SC-FDE在很多场景下比OFDM更实用比如LTE上行、WiFi的某些模式、卫星通信、水下声通信它既有单载波的低峰均比优势又借用频域均衡绕开了时域均衡的高复杂度是一种“取两者之长”的方案。这篇文章我会按一个完整仿真项目的思路来讲先拆清楚系统为什么要这样设计再把发射机、接收机里各个模块的细节和MATLAB实现逐个过一遍最后把我自己调试这种链路时踩过的坑和排查方法整理出来。适合刚接触SC-FDE的通信研究生、准备做基带算法验证的工程师以及想把手里的OFDM代码改成单载波方案的开发人员。看完你基本能照着搭出一条可跑的完整链路。1. 整体设计与思路拆解1.1 为什么选SC-FDE而不是OFDMSC-FDE全称Single-Carrier Frequency-Domain Equalization直译是单载波频域均衡。很多人第一次听到这个名字会有点绕既然是单载波怎么又跑到频域去均衡了简单说发送端还是传统的单载波调制但接收端把一整个数据块做FFT变换到频域在频域完成信道均衡之后再IFFT回时域做判决。SC-FDE和OFDM的核心区别在于OFDM把宽带数据流拆成很多窄带子载波并行传输每个子载波上近似是平坦衰落所以频域均衡特别自然而SC-FDE仍然是串行传输只是借用了“块处理”和FFT来做均衡。OFDM的典型痛点大家都清楚峰均比高对功放线性度要求苛刻对载波频偏敏感。SC-FDE的峰均比和单载波一样低对频偏的敏感程度也远低于OFDM同时又能通过频域均衡处理多径信道。从实现复杂度上看SC-FDE和OFDM的FFT规模是一样的差别主要在多了一个IFFT而且这个IFFT只在接收端出现。所以如果系统对功耗和功放效率要求高或者信道环境里多普勒频偏比较显著SC-FDE往往是比OFDM更稳的选择。这也是为什么它一直是卫星通信、上行链路的备选方案近年在水声通信里也经常被拿来做物理层基础波形。1.2 UW序列在链路里到底干了多少活UW是Unique Word常译作“独特字”或“唯一字”。它本质上是一段收发两端都预先知道的已知序列在SC-FDE帧结构里占据固定位置。我最初以为UW只是拿来当训练序列做同步用的实际把它放在整个链路里看它的作用是多重嵌套的。UW插在每个数据块的前面或后面长度覆盖信道最大时延扩展这时候它起到的作用和OFDM的循环前缀完全一致——保证了数据块与信道之间形成循环卷积频域均衡才能按教科书上的公式来做。与此同时UW本身是已知序列又可以被当作导频或训练序列用来做帧同步、定时同步、频偏估计甚至直接用来做信道估计。一个序列同时承担了CP、导频、同步参考三种角色这正是SC-FDE设计的精巧之处。还有一个细节容易被忽视UW的峰均比特性会影响整个系统的PAPR。如果UW选得不好比如幅度起伏很大会拉高整条链路的峰均比削弱SC-FDE本身的优势。所以实际工程里常用恒包络序列比如ZC序列、Chu序列这样既能维持低PAPR又具有良好的自相关特性方便接收端做相关检测。1.3 帧结构和关键参数要怎么定我在仿真里用的帧结构比较典型每个数据块包含一个UW和一个数据段两者拼接成一个长度为N_FFT的块。假设FFT点数是256UW长度64那数据符号数就是192。把64个UW符号直接放在块头它同时兼任循环前缀。这里有个重要约束UW长度必须大于信道最大时延扩展否则循环卷积条件被破坏均衡性能会明显恶化。实际无线信道里时延扩展通常在几百纳秒到几微秒具体要结合符号速率来换算。仿真时可以先设一个保守值比如面向典型室内多径信道符号速率4Msps时64个符号对应16微秒的保护间隔已经足够覆盖大多数场景。其他参数方面调制用QPSK映射方式选格雷映射目的是让相邻星座点只差一个比特判决错误时误比特数更少。脉冲成型滤波器选根升余弦滚降因子0.22这个取值是很多通信系统的默认选择兼顾带宽效率和时域旁瓣性能。采样率方面我在发射端做4倍上采样接收端先做匹配滤波再抽回符号率这样定时同步的处理空间更大。整个链路设计下来AWGN信道下的理想性能应当逼近QPSK在加性白高斯噪声下的理论误码率这也是验证各个同步模块是否正确的第一道标准。2. 发射链路搭建与核心细节2.1 QPSK映射与符号归一化QPSK映射是整条链路最基础的一步但基础不等于可以随便写。收发两端必须对星座映射表完全一致而且发射端对符号功率要做好归一化否则接收端的信噪比计算会整体偏移。我用的是标准单位能量星座四个星座点分别是(1j)/√2、(1-j)/√2、(-1j)/√2、(-1-j)/√2。这么除一个√2是为了让每个符号的平均能量为1否则后面叠加噪声的时候EbN0和EsN0的换算关系就对不上。写成MATLAB代码就是% QPSK格雷映射 map_table [11j, 1-1j, -11j, -1-1j] / sqrt(2); % 偶数位为I路奇数位为Q路 data_bits randi([0 1], nBits, 1); data_bits_matrix reshape(data_bits, 2, []).; sym_idx bi2de(data_bits_matrix, left-msb) 1; data_syms map_table(sym_idx).;这里用格雷映射能保证相邻星座只差1个比特解调时即使误判到相邻星座也只会造成1比特错误后续硬判决误码率会明显更好看。2.2 数据块格式化和UW插入做完映射之后就要把数据符号和UW拼成完整的传输块。组装顺序我建议先想清楚因为接收端做频域均衡时是以整个块为单位的如果收发两侧对块边界的理解不一致后面全是乱的。我的做法是每192个QPSK数据符号前面拼接64个UW符号组成一个256点的块。UW直接采用ZC序列的频域生成形式再IFFT到时域或者直接在时域生成一段恒包络序列都行。时域直接生成更方便比如nUW 64; nData nFFT - nUW; % ZC序列作为UW根索引选与nUW互质的数 u 1; uw_seq exp(-1j * pi * u * (0:nUW-1) .* (0:nUW-1) / nUW);这种序列的自相关旁瓣很低接收端拿它做相关峰检测尖锐度很好。2.3 成型滤波与发送信号生成成型滤波器在SC-FDE里同样不能省。没有成型滤波的方波信号频谱拖尾很重带外泄漏严重如果后面要加带限信道或者想计算频谱效率结果会很粗糙。我用根升余弦滤波器滚降系数0.22滤波器阶数span设为10个符号周期每个符号4个采样点。sps 4; rolloff 0.22; span 10; tx_filter rcosdesign(rolloff, span, sps, sqrt);这里有个容易忽略的点滤波器有固有延迟滤波之后的信号整体会往后偏移span×sps/2个采样点。接收端做定时同步时如果不把这个延迟考虑进去或者说定时算法本身是在滤波之后的信号上搜峰那倒是问题不大但如果你拿滤波前后的信号做对比或者算误差向量幅度就必须先对齐这个延迟。仿真里我一般会单独记录txDelay这个变量方便后期排查。发射端把每个块串行拼起来之后经过上采样、成型滤波得到的信号就是要送入信道的基带波形。多径信道可以直接用离散卷积实现注意抽头时延要是采样周期的整数倍。如果用到分数时延处理复杂度会上升仿真初期我建议先用整数倍时延把系统调通。3. 接收端三大核心模块定时同步、载波同步与频域均衡3.1 定时同步先粗同步再加细同步接收机拿到的信号首先面对两个基本问题从哪里开始解调以及最佳判决点在哪。这就是定时同步要解决的。SC-FDE是块处理结构所以帧同步和符号定时同步经常合在一起做。我的方案分两步先用UW序列做相关粗同步。接收信号经过匹配滤波后和本地UW序列做滑动互相关相关峰的位置就对应着UW起始时刻。因为ZC序列自相关尖锐即使存在多径主峰也还是比较明显。不过多径会让相关峰展宽所以不能简单取最大值而是取一个能量集中窗的中心这个细节后面在问题排查里细说。粗同步只能把位置确定到采样点精度如果符号同步误差是零点几个采样周期残留的定时偏差会表现为符号间干扰和星座旋转。因此我建议再做一步细同步经典做法是Gardner算法或者OM算法。Gardner在每符号两个采样点时就能工作实现简单适合SC-FDE这种带宽效率较高的系统。实际工程里粗同步和细同步配合使用先定出块边界再做小数倍定时校正两条腿走路才稳。只做粗同步不校正残差星座图边缘会有一圈雾状散点误码率高到匪夷所思。3.2 载波同步从粗频偏估计到残余相偏补偿载波同步要解决两个层面的问题频率偏移和相位偏移。频偏的来源可能是收发两端晶振不同步也可能是多普勒效应。在仿真里我会在发射信号上直接乘一个e^(j2πf_d nT_s)来模拟频偏。粗频偏估计可以用UW序列做延迟相关。具体思路是既然接收端知道UW的确切位置就取两个相隔一定距离的UW片段或者同一块内UW和数据段里的已知位置它们受过相同的信道影响但频偏带来的相位旋转量不同。将两段共轭相乘后取平均其相位差中包含了频偏信息Δφ 2π·f_d·D·T_sym其中D是两个片段的符号间隔T_sym是符号周期f_d是待估计的频偏。所以频偏估计值为delta_f_est angle(sum(conj(r1) .* r2)) / (2 * pi * D * T_sym);这个方法的优点是只需要一次共轭相关计算量小适合作为前馈式粗估计。但要注意它的估计范围受相位模糊限制|Δφ|不能超过π所以能估计的最大频偏是1/(2·D·T_sym)D越大估计精度越高但范围越小。这个矛盾在工程上靠多级估计解决先用小间隔的UW对扫大范围频偏再用大间隔细分估计。粗频偏补偿完之后还会剩一个较小的残余频偏这时候可以用判决辅助的相位估计器循环跟踪。对QPSK信号一个常用的做法是把接收符号取4次方消去调制信息然后提取残余相位误差Δθ angle(mean(r^4)) / 4这个残余相位估计器实现起来非常简单仿真效果也很好。3.3 频域均衡ZF和MMSE要选对频域均衡是整个SC-FDE链路的核心。前面定时同步和载波同步都是为了把一个数据块干净地切出来并补偿掉频偏之后就可以对这个块做FFT在频域逐子载波进行信道均衡。均衡的第一步是做信道估计。最直接的方法是在每个块里利用已知UW做LS信道估计发端UW在频域已知接收端UW的FFT除以发端UW的FFT就得到信道频响估计。实测中UW本身还携带均衡性能提升的可能比如用它做频域插值平滑能减少噪声对信道估计的影响。得到信道频响H(k)之后可以选两种均衡策略迫零均衡系数是W_zf(k) conj(H(k)) / |H(k)|^2它的思路是把信道完全“扳直”噪声会被放大得很厉害尤其是在信道深衰落的频点上一个深零点就能让整块数据性能崩塌。MMSE均衡系数是W_mmse(k) conj(H(k)) / (|H(k)|^2 1/SNR)相当于在信道倒置时加入一个正则项避免在深衰落点上过度放大噪声。这个1/SNR就是噪声方差与信号功率的比值在仿真里可以直接用设定的EbN0换算也可以从接收端数据段里估出来。我强烈建议仿真时两种均衡都实现因为对比出来的结果非常直观在频率选择性较强的信道里MMSE比ZF能带来明显的误码率收益代价只是多算一个噪声方差。均衡完成之后再IFFT回时域接着按数据段位置把UW去掉对数据符号做QPSK硬判决解映射统计误码。整个接收路线可以概括为匹配滤波 → UW相关粗定时 → 细定时校正 → 频偏估计与补偿 → 去UW → FFT → 频域均衡 → IFFT → 判决解调。4. 完整MATLAB仿真流程与关键代码4.1 仿真主框架与参数区我习惯把SC-FDE仿真写成两个文件一个参数初始化脚本一个主循环函数。参数区集中定义所有系统级参数这样跑不同信噪比点、不同信道时不用反复改代码逻辑。%% 系统参数 clear; close all; clc; M 4; % QPSK k log2(M); nFFT 256; % FFT点数即块长度 nUW 64; % UW长度 nData nFFT - nUW; % 数据符号数 nBlocks 100; % 每个SNR点发送的块数 sps 4; % 采样倍数 rolloff 0.22; span 10; EbN0_dB 0:2:14; symbolRate 4e6; % 4 Msps T_sym 1 / symbolRate; % 多径信道参数 channel_taps [1, 0.5, 0.3]; channel_delays [0, 2, 5]; % 整数倍采样点延迟这里channel_taps和channel_delays定义一条简单的三径信道延迟都以采样点为单位。注意最大时延5个采样点远小于UW对应的64个符号长度完全满足循环卷积条件。4.2 发射机完整实现发射机的核心代码逻辑是比特生成 → QPSK映射 → 组装UW与数据块 → 上采样 → 成型滤波 → 加频偏 → 过信道 → 加噪声。% 生成UW序列时域ZC序列 u 1; uw_seq exp(-1j * pi * u * (0:nUW-1) .* (0:nUW-1) / nUW).; tx_filter rcosdesign(rolloff, span, sps, sqrt); txDelay span * sps / 2; % 滤波器延迟 % 主发射循环 for blk 1:nBlocks % 随机比特生成与QPSK映射 bitsTx randi([0 1], nData * k, 1); bits_mat reshape(bitsTx, k, []).; sym_idx bi2de(bits_mat, left-msb) 1; map_table [11j, 1-1j, -11j, -1-1j] / sqrt(2); data_syms map_table(sym_idx).; % 块组装UW 数据 block [uw_seq; data_syms]; % 上采样与成型滤波 block_up upsample(block, sps); tx_signal_blk filter(tx_filter, 1, block_up); tx_signal((blk-1)*length(tx_signal_blk)1 : blk*length(tx_signal_blk)) tx_signal_blk; end上采样直接调upsample在每个符号后面补零然后用成型滤波器内插。因为有滤波器延迟发射信号比理想位置向后偏移了txDelay个采样点这个量在接收端对齐时要留个心眼。4.3 接收机完整实现接收机相对复杂我分块写清楚。首先是匹配滤波和粗定时同步。匹配滤波直接用同一个根升余弦滤波器然后对滤波后的信号和本地UW做滑动互相关。注意本地UW也要上采样到相同的采样率这样相关峰的位置才会落在采样点精度上。% 匹配滤波 rx_mf filter(tx_filter, 1, rx_signal); % 本地UW上采样 uw_up upsample(uw_seq, sps); uw_up_filtered filter(tx_filter, 1, uw_up); uw_ref uw_up_filtered(1txDelay:end); % 对齐滤波器延迟 % 滑动互相关 corr_len length(rx_mf) - length(uw_ref) 1; corr_out zeros(corr_len, 1); for n 1:corr_len corr_out(n) abs(sum(rx_mf(n:nlength(uw_ref)-1) .* conj(uw_ref))); end相关峰会出现在每个UW的起始位置附近。块与块之间的间隔是固定的所以可以只搜索第一个峰然后按块的采样长度推算出后续所有块的位置。这个思路比每块都搜峰更稳能避免个别块在多径深衰落时相关峰太小的问题。粗同步之后是频偏估计。利用同一块内UW尾部和自己做延迟相关的思路或者直接用上一块和下一块的UW相关。频偏估计代码已经在上文给出重点是D的选取。实测时我用D32个符号间隔既能覆盖±1%符号率的频偏精度也够用。载波同步完成后把每个块从接收信号中切出来去掉循环前缀也就是UW对数据段做FFT前先要把UW去掉还是保留这里要特别说明频域均衡的处理对象是整个数据块如果UW作为CP放在块头切块时可以把UW部分一起保留均衡后再丢弃。这意味着FFT的输入是完整的256点块循环卷积条件才能成立。只是MMSE均衡后的输出需要把前面64个UW符号对应的位置丢弃只保留后面192个数据符号做判决。这种做法更贴近实际系统。频域均衡的代码核心是信道估计和均衡系数计算% 去除相邻块之间的拖尾按块切分 % 对于每个块 rx_block rx_signal_blk; % 长度为 nFFT*sps 的采样块 % 抽取符号级样本考虑定时同步给出的最佳采样点偏移 rx_syms rx_block(bestOffset : sps : end); % 取256个符号 % FFT RX fft(rx_syms, nFFT); % 用UW做信道估计已知UW的FFT为UW_F H_est RX(1:nUW) ./ UW_F; % 对UW对应的频点 % 插值得到全部频点信道估计简单起见可用全部块的UW平均 H_full interp1(..., H_est, ..., linear, extrap); % MMSE均衡 SNR 10^(EbN0/10) * (nData / (nFFT * sps)); % 换算 W_mmse conj(H_full) ./ (abs(H_full).^2 1/SNR); % 均衡输出 Y_eq RX .* W_mmse; y_eq ifft(Y_eq, nFFT); % 丢弃UW对应符号保留数据 data_eq y_eq(nUW1:end); % QPSK判决与解映射这里信道估计我只写了思路因为细节处理可以有很多变体。实用中更稳妥的做法是整个仿真开始前先用一段全UW的探测块把信道估计出来后面直接复用。因为仿真信道是静态的这样能省去逐块估计的复杂度也便于验证均衡算法本身。4.4 误码率统计和理论曲线对比主循环对每个EbN0点做蒙特卡洛统计比较发送比特和解调比特计算误码率。QPSK在AWGN下的理论误码率公式是Pb Q(√(2·EbN0))在MATLAB里用0.5erfc(sqrt(EbN0))或者qfunc(sqrt(2EbN0))计算。多径信道时没有这么简单的闭式解但可以用无频偏、理想信道估计、MMSE均衡的仿真结果作为系统参考上界。我觉得验证链路正确性的最好办法就是先跑AWGN信道。如果AWGN下你的仿真误码率曲线和理论曲线重合说明调制解调、定时同步、载波同步、均衡这几大件基本没问题然后再切换到多径信道此时再观察性能损失是否合理。很多新手一上来就放多径信道结果曲线乱七八糟根本定位不了是哪个模块的问题。先易后难调链路也是这样。5. 常见问题与排查技巧实录5.1 相关峰展宽或峰值偏移多径信道下UW互相关输出的峰不再是一个尖锐的点而是多个路径峰值的叠加。如果直接取最大值所在位置作为定时点往往会偏向最强径而非第一径造成定时偏移。我的处理方法是先对相关功率做滑动窗积分能量窗长度取信道最大时延扩展对应的采样点数再取能量窗的中心作为同步位置。这个办法在多径环境下比单纯找峰稳得多。另外要注意本地UW参考序列的滤波器延迟对齐。如果接收端匹配滤波和成型滤波共用同一个滤波器本地参考也要经过相同的滤波并截掉同样长度的延迟否则相关峰位置会差一个固定偏移导致每块都切偏。5.2 残余频偏表现为星座旋转粗频偏补偿之后如果还有剩余频偏最直观的现象是QPSK星座点随着符号序号逐渐旋转块首的符号相位误差小块尾的符号相位误差大。这种旋转如果用硬判决直接解调块尾符号会大量误判。对策是加入判决辅助的残余相位跟踪。一个简单的实现是逐符号估计相位误差后用一阶环路滤波但仿真里更省事的办法是每个块做完频域均衡、IFFT回时域后利用UW处的已知符号估计剩余公共相偏然后对整个块的数据做共轭旋转。因为频偏在块内造成的相位旋转是累加的这个方法相当于把整块的公共相偏消掉配合前面粗频偏已经足够把QPSK星座拉回正位。5.3 MMSE均衡的噪声方差取不准MMSE均衡系数里的1/SNR直接决定均衡器是在“信道倒置”和“噪声抑制”之间取怎样的折中。如果在低信噪比区把SNR设得过高均衡器会偏向ZF噪声放大明显在高信噪比区把SNR设得过低均衡器又过度平滑深衰落频点得不到补偿残余码间干扰严重。仿真里有一个有效技巧用数据段本身的接收信号来估计噪声方差。每块均衡前可以把UW位置的均衡误差统计出来因为UW是已知的这个误差里主要就包含了噪声和残余干扰可以用它来动态更新SNR估计。实测下来这种自适应SNR估计比固定参数更稳。5.4 滤波器延迟补偿被遗漏这是新手最常踩的坑。成型滤波和匹配滤波各引入一次span×sps/2的延迟总延迟就是span×sps。如果定时同步是在匹配滤波之后做的那么发射端的第一个滤波延迟已经隐含在信道时延里不会额外造成问题。但如果把滤波器输出直接当作理想时刻的信号用理论位置去切块就会看到整个星座整体旋转或者眼图张开度不足。排查这类问题最简单的办法是发一个纯UW块不加载波同步直接观察相关峰位置与理论位置的差这个差值就是滤波器延迟加上信道时延。5.5 问题速查表现象大概率原因处理办法星座图整体旋转残余频偏未补偿增加残余相偏估计环路星座图呈环状散点定时采样点偏移较大检查相关峰定位和细同步深衰落频点附近噪声极大用ZF均衡且信道有深零点改用MMSE核实SNR估计高信噪比误码率地板下不去滤波器延迟未对齐校准发射/接收滤波器延迟相关峰多个且平缓多径时延大于UW长度加大UW长度或降低符号率UW块前后数据BER差异大循环卷积条件被破坏确认UW长度覆盖最大时延扩展我在自己调这条链路的时候体会最深的一点是不要同时引入太多新变量。SC-FDE的模块彼此耦合很紧密定时同步不准会让频偏估计出问题频偏补偿不完全又会让信道估计不准最终全堆在均衡上。所以每一步都要单独验证先发纯UW验证同步再发已知数据验证均衡最后才上随机比特做误码率统计。这个方法虽然慢但排查问题一找一个准。最后再分享一个小技巧跑仿真时把每一步的中间结果比如定时误差、频偏估计值、均衡前的信噪比估值都打印或画出来看一眼。你花十分钟看这些中间量往往比在误码率曲线上猜原因节省几小时。链路通了之后你还可以把QPSK换成16QAM或者把ZC序列换成其他UW设计看看性能怎么变化——这套框架是能直接扩展的。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表