频分复用通信模型MATLAB仿真:从频谱切片到滤波器组解调
简介一套频分复用通信系统仿真资料基于MATLAB平台实现面向通信工程专业学生、课程设计者以及希望掌握复用与解复用原理的入门读者。资源包共包含4个文件全部为核心仿真内容其中3个脚本文件分别负责主程序搭建、带通滤波处理和音频信号获取1个数据文件提供可直接调用的实测音频数据便于对照观察频分复用系统从调制、复用、传输到解复用的完整链路。目前已有1500余人学习实用性经过较多验证。通过运行源码并阅读代码注释读者可以深入理解频率划分、频谱搬移和滤波器设计等关键思路还可修改参数拓展为多路基带信号频分复用实验对课程设计、实验报告和毕业设计均有较强参考价值。1. 频分复用通信模型仿真的本质先理解“频谱切片”再谈 MATLAB 实现频分复用Frequency Division Multiplexing, FDM是所有多路复用技术里最直观、也最容易被初学者误解的一种。直观在于它把一条物理信道的可用带宽按频率切成互不重叠的若干条子信道各路信号各自占据一个频段互不打扰误解则在于很多人在第一次做 MATLAB 仿真时以为“把两个正弦波加起来”就是频分复用了——这在数学上没错在通信模型上却远远不够。真实的 FDM 系统要解决的是如何让接收端不仅能看到信号还能从混合频谱里把某一路干净地“切”出来。这个“切”的动作决定了整个仿真的核心复杂度。本文围绕“频分复用通信模型 MATLAB 仿真研究”这一主题从基带信号设计、子载波分配、调制合路、滤波器组解调再到频谱效率与误码率分析给出一条完整的仿真路径。无论你是正在做课程设计、准备通信原理实验还是需要在项目里快速验证一个多路传输方案这篇文章都会覆盖“参数怎么设、代码怎么写、出问题时看哪里”这几个关键点。但需要先明确一个前提本文讨论的是带通滤波加频谱搬移的经典 FDM 模型不是 OFDM 那种基于 IDFT/DFT 的并行传输体制——两者的数学结构有本质差异混为一谈会给仿真带来不可控的误差。2. 建立频分复用模型从“信道带宽划分”推导出数学表达再落到仿真参数矩阵2.1 为什么频分复用模型可以用一个简单的数学式表示在 MATLAB 仿真里我们不需要从 Maxwell 方程出发。通信系统仿真遵循的是“等效复基带”思想所有射频载波都可以在数学上等价地建模为复指数信号的实部。一路经过调制的 FDM 发送信号数学形式如式(1)所示[ s(t) \sum_{i1}^{N} \sqrt{P_i} \cdot m_i(t) \cdot \cos(2\pi f_i t \phi_i) ]其中 ( N ) 为子信道总数( P_i ) 是第 i 路信号的发射功率( m_i(t) ) 是第 i 路基带调制信号( f_i ) 第 i 路子载波中心频率( \phi_i ) 是初始相位。这个式子的物理含义很清晰发送信号就是 N 个被搬移到不同频谱位置的独立信号的线性叠加。但这里要特别注意一个仿真的关键点——子载波间隔的设计。理论上只要各路信号频谱互不重叠接收端就可以用理想带通滤波器把它们分开。现实中不存在理想滤波器因此工程上必须预留保护间隔Guard Band。设某路基带信号的最高频率为 ( f_{max} )则相邻子载波的频率间隔应满足 ( \Delta f 2f_{max} )。如果采用滤波器阶数较低、滚降特性较缓的 FIR 滤波器这个间隔还要进一步放大。2.1.1 仿真中的离散化映射关系决定采样率必须先于一切参数设定MATLAB 的仿真对象是离散序列不是连续函数。因此必须在写任何代码之前先把物理参数映射到数字域。物理量符号离散域对应关系仿真步长( \Delta t )( 1 / F_s )子载波频率( f_i )( f_i / F_s )归一化频率基带码元速率( R_b )每个码元对应的采样点数 ( SPS F_s / R_b )仿真总时长( T )( N_{samples} T \cdot F_s )采样率的设定在频分复用仿真里尤其重要。假如系统共 4 路、每路采用 BPSK 调制、码元速率 1kbps子载波频率分别是 4kHz、8kHz、12kHz、16kHz那么采样率至少需要大于 2 倍最高子载波频率加信号带宽。奈奎斯特采样定理给出理论下限但在 FDM 仿真里我会额外加一个 1.21.5 倍的过采样系数原因在后面的代码部分会解释。提示不要图省事直接用理论最低采样率。频分复用仿真涉及带通滤波和频谱搬移滤波器群延迟和边缘效应会让时域波形在端点处失真过采样可以显著降低这种边界效应对误码率统计的影响。2.2 用 MATLAB 搭建频分复用发送端模型的三个核心步骤发送端模型的本质是“基带成型 子载波调制 频谱合路”。下面这个代码实现的是一个 4 路 BPSK-FDM 系统每路码元速率 1kbps子载波间隔 4kHz确保频谱完全分离。% FDM_Transmitter.m % 参数配置 Fs 64e3; % 采样率64kHz满足过采样需求 Rb 1e3; % 每路码元速率 1kbps SPS Fs / Rb; % 每个码元的采样点数 64 Nsym 200; % 仿真码元数 Nch 4; % 子信道数量 fc [4e3, 8e3, 12e3, 16e3]; % 子载波中心频率 % 生成随机二进制码元 rng(42); data randi([0 1], Nch, Nsym); % BPSK 映射: 0 - -1, 1 - 1 symbols 2*data - 1; upsampled zeros(Nch, Nsym*SPS); for ch 1:Nch % 插值每个码元重复 SPS 次矩形脉冲成型 upsampled(ch, :) reshape(repmat(symbols(ch,:), SPS, 1), 1, []); end % 时域采样轴 t (0 : Nsym*SPS - 1) / Fs; % 调制合路 tx_signal zeros(1, Nsym*SPS); for ch 1:Nch carrier sqrt(2) * cos(2*pi*fc(ch)*t); % sqrt(2) 是为了归一化功率 tx_signal tx_signal upsampled(ch,:) .* carrier; end % 绘制时域波形和频谱 figure(1); subplot(2,1,1); plot(t(1:512), tx_signal(1:512)); xlabel(时间 (s)); ylabel(幅度); title(FDM 发送信号时域波形前512点); grid on; subplot(2,1,2); Nfft 8192; f_axis (-Nfft/2:Nfft/2-1) * Fs / Nfft; spec fftshift(abs(fft(tx_signal, Nfft)).^2 / Nfft); plot(f_axis/1e3, 10*log10(spec eps)); xlabel(频率 (kHz)); ylabel(功率谱密度 (dB)); title(FDM 发送信号频谱); xlim([0 25]); grid on;这段代码里有几个参数需要特别说明。其一sqrt(2)这个系数不是随手写的。BPSK 的每个符号能量被平均分配到余弦载波的正负半周期上不乘这个系数接收端解调出的信号幅度会偏低 3dB直接影响后续信噪比计算的准确性。其二repmat配合reshape实现的上采样本质是零阶保持对应频域是 ( \text{sinc} ) 函数形状的功率谱包络主瓣零点出现在码元速率整数倍处——这就是为什么子载波间隔要远大于码元速率否则相邻信道的频谱尾瓣会重叠。2.3 频分复用链路级仿真模型从比特到波形的完整抽象把发送端和接收端串起来就构成了一个完整的链路级仿真模型。在这个模型里噪声、滤波器、同步偏差都是可配置的模块。先给出整体框架后面逐步填充各模块的实现。% FDM_Link_Simulation.m %% 第1步系统参数声明 Fs 64e3; Rb 1e3; SPS Fs / Rb; Nsym 1000; Nch 4; fc [4e3, 8e3, 12e3, 16e3]; EbN0_dB 10; % 每比特信噪比单位 dB %% 第2步发送端 % 生成数据和 BPSK 符号同 2.2 节这里省略具体行 % 叠加成形、调制得到 tx_signal %% 第3步信道AWGN snr_linear 10^(EbN0_dB/10); % 每路信号功率归一化为1总信号功率 Nch signal_power Nch; noise_power signal_power * SPS / (2 * snr_linear); noise sqrt(noise_power) * randn(size(tx_signal)); rx_signal tx_signal noise; %% 第4步接收端解调将在第3章详细展开 %% 第5步误码率统计 % 对比发送数据和解调数据计算 BER注意这个模型中noise_power的计算方法。通信仿真里最常犯的错误就是把 AWGN 的方差设成一个拍脑袋的数值。这里 ( N_0 S / (R_b \cdot 10^{E_b/N_0/10}) )而离散域的噪声方差要乘以 ( F_s/2 )原因是采样后的噪声带宽是 ( \pm F_s/2 )只有这一半带宽内的噪声功率会进入信号频带。这个换算关系直接决定了误码率曲线是否会和理论值重合。3. 频分复用接收端仿真的设计与滤波器组解调频域切割是唯一正确的打开方式3.1 为什么频分复用接收端仿真必须用滤波器组而不是 FFT 直接切片很多人做频分复用接收端时会想发送端是多个频段的叠加那接收端直接对整个信号做 FFT然后在频域把不同子载波的频谱分量挑出来再做 IFFT 恢复各路信号可行吗理论上有一定可行性但实际仿真中会碰到两个致命问题。FFT 的频率分辨率是 ( F_s / N_{fft} )如果子载波频率不是频率分辨率的整数倍频谱泄漏会让相邻信道串扰。补零能改善显示效果但不能提高真实分辨率。更重要的是通信系统是流式处理的接收到的数据是一段一段到达的FFT 要攒够一帧才能处理引入的延迟在 FDM 点对点通信里不可接受在多跳中继场景下更是致命的。所以标准做法一直是——滤波器组。接收端为每路子信道配置一个带通滤波器只允许本路频谱通过滤除其他路信号。这个方案的物理含义极清晰每个滤波器的通带就是分配给该路信号的“频谱切片”。3.1.1 滤波器参数设计公式与 MATLAB 实现滤波器的设计有几个相互冲突的指标过渡带宽度、通带纹波、阻带衰减、滤波器阶数。对 FDM 系统来说最重要的约束是相邻信道的频谱间隔。如果子载波间隔是 4kHz、基带信号主瓣宽度是 2kHz滤波器过渡带要落在 2kHz 到 4kHz 之间的区域即过渡带最宽不能超过 2kHz。设计一个实际的 FIR 带通滤波器用firpm或designfilt都可以。下面给出一个用凯泽窗设计带通滤波器的完整操作% DesignBPF_FIR.m Fs 64e3; fc_target 8e3; % 目标子载波中心频率 bw_pass 2e3; % 通带宽度 ±1kHz bw_stop 4e3; % 阻带起始偏移 ±2kHz % 使用 designfilt 设计等纹波 FIR 带通滤波器 bpFilt designfilt(bandpassfir, ... StopbandFrequency1, fc_target - bw_stop, ... PassbandFrequency1, fc_target - bw_pass, ... PassbandFrequency2, fc_target bw_pass, ... StopbandFrequency2, fc_target bw_stop, ... StopbandAttenuation1, 60, ... StopbandAttenuation2, 60, ... PassbandRipple, 0.5, ... SampleRate, Fs, ... DesignMethod, equiripple); % 查看滤波器幅频响应 fvtool(bpFilt); % 滤波 y_filtered filter(bpFilt, rx_signal);这个滤波器把通带设为 7kHz9kHz阻带截止在 6kHz 和 10kHz过渡带宽度正好 1kHz。阻带衰减 60dB 意味着相邻子信道的泄漏被压制到比信号弱 1000 倍以下基本不影响误码率。PassbandRipple设为 0.5dB这个值如果太小比如 0.1dB滤波器阶数会急剧上升但换来的是解调信号幅度更平稳星座图上点的聚合度更好。仿真时可以根据实际需要调整这个参数。注意filter函数会引入群延迟在符号判决之前必须把延迟补偿掉。grpdelay(bpFilt)可以查看具体数值补偿长度约为滤波器阶数的一半。这个问题在后面会单独展开。3.2 完整解调链路带通滤波、相干下变频、匹配滤波、判决带通滤波只是把频谱“切”出来了这时候信号还是位于子载波频段的带通信号需要把它搬回基带再判决。整个解调链路的顺序不能颠倒。% FDM_Receiver.m % 循环处理每个子信道 for ch 1:Nch % 第一步带通滤波提取目标频段 bpFilt_ch designfilt(bandpassfir, ... % 参数同 3.1.1 StopbandFrequency1, fc(ch) - 2e3, ... PassbandFrequency1, fc(ch) - 1e3, ... PassbandFrequency2, fc(ch) 1e3, ... StopbandFrequency2, fc(ch) 2e3, ... StopbandAttenuation1, 60, ... StopbandAttenuation2, 60, ... PassbandRipple, 0.5, ... SampleRate, Fs, DesignMethod, equiripple); y_bp filter(bpFilt_ch, rx_signal); % 第二步乘以本地载波相干解调假设载波同步已恢复 t (0:length(y_bp)-1) / Fs; y_baseband sqrt(2) * y_bp .* cos(2*pi*fc(ch)*t); % 第三步低通滤波去除 2 倍频分量 lpFilt designfilt(lowpassfir, ... PassbandFrequency, 1.2e3, StopbandFrequency, 2e3, ... PassbandRipple, 0.5, StopbandAttenuation, 40, ... SampleRate, Fs); y_lp filter(lpFilt, y_baseband); % 第四步抽取与判决 % 先修正滤波器群延迟 delay_bp grpdelay(bpFilt_ch, 1, Fs); delay_total round(mean(delay_bp) grpdelay(lpFilt, 1, Fs)); y_sync y_lp(delay_total1 : end); % 按 SPS 抽样取每个码元中间点 samples y_sync(round(SPS/2) : SPS : length(y_sync)); samples samples(1:Nsym); % 对齐长度 % BPSK 判决 rx_bits double(samples 0); % 计算该路子信道误码率 ber_ch(ch) sum(rx_bits ~ data(ch,:)) / Nsym; end解调链路中第二步的乘法是关键。乘以cos(2*pi*fc*t)之后信号频谱被复制成两份一份搬回基带一份搬到 ( 2f_c ) 处。第三步的低通滤波器就是要把后者干掉。如果低通滤波器的截止频率太靠近信号带宽边缘信号的高频分量会被削掉表现为眼图“眼皮变厚”如果太宽2 倍频分量的残余会混进来表现为判决点附近的高频抖动。3.3 仿真发散判断滤波器的群延迟和符号定时偏移是两大根因“仿真发散”在频分复用场景里很少是指数值溢出更多是指误码率居高不下或波形乱成一团。最常见的两大根因一个是滤波器群延迟没有补偿另一个是符号定时偏移。群延迟问题上面已经处理——delay_total把带通和低通两级滤波器的延迟都算进去再对齐。符号定时偏移则更隐蔽round(SPS/2)假设最佳采样点在码元中间但这是在没有考虑相邻码元干扰的前提下才成立。如果滤波器阶数很高群延迟可能不是一个整数倍的采样周期这时候直接按round取整会引入亚采样级偏移。处理办法是插值重采样先用resample把信号插到更高采样率再抽样或者用 MATLAB 的interp1在最佳采样点处做线性插值。在实际项目中我更倾向把 SPS 设成 64 或 128 这种较大的值把亚采样偏移对误码率的影响摊薄然后用上面代码里的方式对齐就够了。4. 频分复用通信模型仿真性能分析频谱效率、子载波间隔约束和误码率验证4.1 同一套频分复用参数如何算出理论频谱效率来约束仿真预期做了仿真不能只看波形还要看系统级指标。频分复用系统最核心的指标就是频谱效率。一个 N 路、每路码元速率 ( R_b ) 的 FDM 系统总占用带宽 ( B_{total} ) 由式(2)给出[ B_{total} N \cdot (2f_{max} \Delta f_{guard}) \text{边缘保护带} ]其中 ( 2f_{max} ) 是单路信号的理论最小带宽奈奎斯特准则( \Delta f_{guard} ) 是保护间隔边缘保护带是为了让最高和最低子信道避开信道的截止区域。频谱效率 ( \eta (N \cdot R_b) / B_{total} )。在设计仿真参数时可以用这个公式逆向验算如果目标频谱效率是 0.5 bit/s/Hz那么保护间隔和边缘保护带要压得多小保护带越小滤波器阶数要求越高计算量越大。仿真 4 路 BPSK 信号、码元速率 1kbps子载波间隔取 4kHz总带宽约 20kHz数据率 4kbps频谱效率只有 0.2 bit/s/Hz。这个效率很低但换来的是接收端只用 40 阶左右的滤波器就能获得 60dB 的邻道抑制仿真速度极快适合作为基准模型。后续要提升频谱效率一个直接的手段是把 BPSK 换成 QPSK让每路信号在相同带宽内携带 2 比特信息。4.2 子载波间隔的三个约束条件频谱不重叠、可实现滤波、载波同步裕量子载波间隔的取值不是拍脑袋定的它同时受三个约束条件支配。第一个约束是频谱不重叠。这是最基本的要求前面已经反复强调。第二个约束是滤波器可实现性。理论上保护间隔可以任意小但滤波器过渡带要做到非常窄阶数就要非常高。100 阶 FIR 滤波器的过渡带宽度大约是 ( 4/(N1) \cdot F_s )在 64kHz 采样率下约 2.5kHz。如果子载波间隔只有 3kHz那么过渡带已经把整个保护间隔吃掉了滤波器幅频响应边缘会顶到相邻信号频谱边缘实测邻道抑制会急剧恶化。第三个约束是载波同步裕量。接收端的本地振荡器不可能和发送端完全同频存在一个频偏量。频偏会让滤波后的信号频谱产生平移如果子载波间隔太密频谱平移后就会拱进相邻信道。预留 5%10% 的子载波间隔作为同步裕量是工程上的常见做法。把这三个约束写成一张参数设计检查表约束类型检查方法仿真中如何验证频谱不重叠计算功率谱密度观察相邻子载波主瓣是否相交于 -40dB 以下对比叠加信号和各路单独信号的功率谱滤波器可实现查看滤波器阶数阶数超过 500 要重新考虑filter运行耗时或fvtool显示幅频响应载波同步裕量手动给本地载波加 1% 频率偏移观察误码率变化在本地载波频率上乘一个偏差系数4.3 MATLAB 频分复用仿真的误码率统计单次仿真的波动与蒙特卡洛平均单次仿真的误码率是不可信的。200 个码元如果出现 2 个错误误码率是 0.01但再多跑 200 个码元可能一个错误都没有误码率骤降为 0。因此误码率统计必须做蒙特卡洛平均。% BER_MonteCarlo.m EbN0_dB 0:2:16; num_trials 20; ber_results zeros(length(EbN0_dB), Nch); sim_BER zeros(1, length(EbN0_dB)); for idx 1:length(EbN0_dB) total_errors zeros(1, Nch); total_bits 0; for trial 1:num_trials % 运行 FDM_Link_Simulation.m 中的代码把 EbN0_dB 改成变量 % 得到每路误码数 err_count_ch 和发送比特数 nbits for ch 1:Nch total_errors(ch) total_errors(ch) err_count_ch(ch); end total_bits total_bits nbits; end sim_BER(idx) sum(total_errors) / (num_trials * total_bits); end % 与理论 BPSK 误码率对比 theory_BER 0.5 * erfc(sqrt(10.^(EbN0_dB/10))); figure(2); semilogy(EbN0_dB, sim_BER, ro-, LineWidth, 1.5); hold on; semilogy(EbN0_dB, theory_BER, b-, LineWidth, 1.5); xlabel(Eb/N0 (dB)); ylabel(误码率); legend(FDM 仿真 BER, BPSK 理论 BER); grid on;把仿真曲线和理论曲线画在一张图上可以看到在低信噪比区域06dB两者贴合良好在高于 10dB 的高信噪比区域仿真曲线会偏离理论曲线出现一个平台效应。这个平台就是滤波器的邻道泄漏和符号间干扰共同限定的误差地板。想降低这个平台方法只有一个——增加滤波器的阻带衰减或增大子载波间隔。这个误差地板不是噪声带来的而是系统自身设计引入的干扰这正是频分复用仿真最有价值的部分。5. 频分复用通信模型的工程化改进与验证从“能跑通”到“可交付”5.1 把矩形脉冲成型换成根升余弦滤波器直接压低误差地板前面仿真用的是矩形脉冲成型频谱是 sinc 形状旁瓣以 ( 1/f ) 的速率衰减第一旁瓣只比主瓣低约 13dB。这意味着即使子载波间隔足够大相邻信道的频谱尾巴也会渗入本路信号的通带。工程上解决这个问题的方法是用根升余弦RRCRoot Raised Cosine滤波器做脉冲成型。RRC 滤波器有两个关键参数滚降因子 ( \beta )01和符号周期。( \beta ) 越小频谱越紧凑但时域拖尾越长( \beta ) 越大频谱越宽但时域衰减越快。在 FDM 系统里( \beta ) 的典型取值是 0.20.5。发送端用 RRC 成型接收端再用同样的 RRC 匹配滤波两者级联后构成升余弦滤波器理论上可以做到零符号间干扰。% RRC_pulse_shaping.m beta 0.35; % 滚降因子 span 10; % 滤波器截断长度符号数 sps SPS; % 每符号采样数 % 生成 RRC 脉冲响应 rrcFilter rcosdesign(beta, span, sps, sqrt); % 发送端对每路上采样后的符号序列做卷积 tx_shaped_ch1 upsampled(1,:); % 未成型信号 tx_shaped_ch1 conv(tx_shaped_ch1, rrcFilter, same); % 接收端带通滤波、下变频之后再做 RRC 匹配滤波 y_matched conv(y_lp, rrcFilter, same);把这段代码替换掉 2.2 节的矩形脉冲成型后你会发现两个变化发送信号的频谱旁瓣被压得很低相邻子信道的干扰明显减小接收端波形在判决点处的“眼睛”张得更开。代价是 RRC 滤波器引入的时延扩展——span10意味着一个符号的能量扩散到前后共 10 个符号的区间内。这不会引入误码因为接收端的匹配滤波会把这些能量重新聚合回判决点。5.2 频偏自检清单两段测试代码定位频分复用链路问题工程落地的最后一步是建立一套验证链路健康度的方法。推荐一个两步走的测试流程。第一步环路测试。把发送信号直接加噪声后接回接收端不改任何参数。如果这一步误码率不符合理论预期问题一定出在调制解调代码本身与信道无关。第二步频偏敏感性测试。在接收端乘以一个有人为频偏的载波% FreqOffset_Test.m offset_ratio 0.01; % 频偏为子载波间隔的 1% f_offset offset_ratio * (fc(2) - fc(1)); % 40Hz t_local (0:length(rx_signal)-1) / Fs; rx_lo rx_signal .* exp(1j*2*pi*f_offset*t_local); % 复混频 % 后续取实部再走正常解调链路如果 1% 的频偏就让误码率显著恶化说明滤波器的通带余量留得太小应该把子载波间隔放大或改用更宽的通带、更高的滤波器阶数。这比直接盯着频谱图看要可靠得多——频谱图是宏观视角误码率是微观视角两者结合才能把问题定位准确。5.3 资源与精度权衡一套适用于 60GHz 毫米波频分复用回传的 MATLAB 参数模板作为收尾给出一个实际的工程参数模板。这个模板模拟的是毫米波频分复用回传链路中的中频部分把 4 路 200Mbps 的 QPSK 信号频分复用成一路 800Mbps 的聚合信号。采样率设为 4GHz子载波频率按 500MHz 间隔排列RRC 滚降因子 0.25。这个配置在降低邻道干扰和节省频谱资源之间取了一个折中。仿真时先跑通基带模型再把载波频率整体上调到中频段逐步逼近真实系统指标。这个模板不是唯一答案但任何偏离这个模板的做法都应该给出“为什么”的理由。技术选型最忌讳的就是说不出理由的随意参数。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →