
简介本资源是一份面向通信工程专业本科生及数字信号处理初学者的Matlab实践项目聚焦信道化收发系统设计这一核心通信课题解决多信道频谱复用与高效滤波实现问题。项目基于多相滤波器原理构建信道化发射机与接收机涵盖基带信号上采样调制、滤波器组信道划分、下采样解调与信道分离等关键环节适用于课程设计、毕业设计及通信系统仿真入门。压缩包共3个文件2个Matlab源码文件用于发射/接收流程实现1张系统结构示意图PNG总容量仅102KB轻量易读代码结构清晰、注释完整便于理解多相分解逻辑、upfirdn与滤波器组协同机制及信道化处理全流程。已有1122人学习下载读者可直接运行验证信道隔离效果掌握FIR滤波器设计、多相结构编程及filterbank思想的实际应用为后续研究OFDM、FBMC或软件无线电打下扎实基础。1. 为什么信道化处理非得用多相滤波器——从“暴力拼接”到“优雅分解”的技术跃迁你有没有试过在Matlab里直接用几十个并行的FIR滤波器去实现一个64路信道化发射机我试过。那是在做某型宽带数字中频系统时按传统思路写了个for循环调用filter()对每一路子带信号单独滤波、下采样再搬移到各自中心频率。结果呢仿真跑完要等三分钟内存峰值飙到12GB生成的C代码在FPGA上根本没法综合——资源占用超限5倍。后来我才明白这不是Matlab慢是方法错了。信道化发射/接收的本质不是“堆滤波器”而是“结构化分解”。而多相滤波器Polyphase Filter Bank就是把一个高阶、高采样率的原型滤波器像拆解乐高一样按时间索引分组变成一组低阶、低采样率的子滤波器集合。它不改变最终频响却让计算量从O(N×M)降到O(N)其中N是原型滤波器长度M是信道数。这个“降维打击”级的优化不是数学游戏是工程落地的生死线。多相滤波器的核心思想是利用采样率变换中的抽取与插值对偶性。举个生活化的例子你想把一整块大蛋糕原始宽带信号切成64块均匀小蛋糕64个子信道传统做法是请64个厨师64个独立滤波器同时开工每人拿一把大刀长滤波器切同一块蛋糕的不同位置——刀重、动作慢、还容易互相干扰。而多相结构相当于先把蛋糕按特定节奏切成条多相分解再由64个助手子滤波器每人只负责切一条里的固定几片——刀轻、动作快、流水线作业。这里的“特定节奏”就是原型滤波器系数按模M信道数取余的分组规则。比如一个长度为128的原型低通滤波器h[n]当M64时它的多相分量就只有两组E₀[k] h[2k] 和 E₁[k] h[2k1]每组长度仅64。这直接把计算量砍掉一半。更关键的是这些子滤波器可以工作在远低于原始采样率的速率下——发射端插值后先滤波再抽取接收端先抽取再滤波后插值整个数据流在内部以1/M的速率流动硬件资源和功耗自然大幅下降。这个结构之所以在Matlab里特别值得深挖是因为它完美契合了Matlab的向量化计算范式。你不需要写for循环去挨个调用filter而是用矩阵乘法或FFT批量处理所有信道。Matlab的polyphase函数族如mfilt.firsrc,mfilt.firint底层就是基于此但它们封装太深掩盖了关键细节。真正要吃透必须亲手推导多相矩阵、理解DFT调制与IDFT合成的内在联系。这也是为什么网上搜“matlab 信道化”出来的教程90%都卡在“调用现成函数”这一步一旦需要定制滤波器响应、处理非理想信道间隔、或者对接FPGA定点实现就全懵了。本文接下来要做的就是带你从零开始用最朴素的Matlab原生语法一行行写出可调试、可验证、可移植的多相信道化收发机把那些藏在comm.Channelizer和comm.DigitalDownConverter黑盒背后的齿轮一颗颗拧开给你看。2. 多相滤波器银行的数学骨架从原型滤波器到多相分量的完整推导链要让多相结构真正“活”起来第一步是彻底搞懂它的数学骨架。这绝不是抄几行公式就能糊弄过去的因为每一个符号背后都对应着Matlab里一个具体的数组索引、一次矩阵转置、或一个FFT点的物理意义。我们从最基础的原型滤波器设计开始逐步拆解到多相分量全程用Matlab思维来组织。2.1 原型滤波器信道化系统的“心脏”与约束条件信道化系统的性能80%取决于原型滤波器的设计。它不是一个普通的低通滤波器而是一个被严格约束的“整形器”。其核心指标有三个缺一不可归一化带宽Normalized Bandwidth设总带宽为B信道数为M则每个子信道的理想带宽是B/M。原型滤波器的3dB截止频率必须精确设为π/M弧度/样本这是保证各子信道在频域上无重叠又无缝隙的理论基础。在Matlab里这意味着用fdesign.lowpass时NormalizedFrequency参数必须设为1/(2*M)而不是笼统的0.5。阻带衰减Stopband Attenuation这是抑制邻道干扰的关键。实测发现当阻带衰减低于60dB时相邻信道的串扰ACI会急剧恶化导致误码率BER在信噪比SNR20dB时不再下降。因此我习惯用kaiserord配合fir1设计将Astop设为65dB并手动检查freqz响应曲线在ωπ/M±π/(2M)处的衰减是否真达标。很多教程直接用firpm但Kaiser窗在通带纹波和阻带衰减的平衡上更稳健。群延迟平坦度Group Delay Flatness信道化系统要求所有子信道的相位响应尽可能线性否则不同频率分量到达时间不同解调时会产生符号间干扰ISI。这要求原型滤波器必须是线性相位FIR。在Matlab中这意味着滤波器长度L必须为奇数且系数必须满足h[n] h[L-1-n]。你可以用islinphase(h)函数验证但更保险的做法是在设计时就指定Type为hilbert或differentiator之外的类型并强制L 2*floor(L/2)1。下面是一段经过千锤百炼的原型滤波器设计代码它把上述三点全部固化function h_proto design_prototype_filter(M, Fs, Astop) % M: 信道数 % Fs: 原始采样率 (Hz) % Astop: 阻带衰减 (dB) % 1. 计算归一化截止频率 Fc_norm 1/(2*M); % 对应 π/M 弧度/样本 % 2. 估算滤波器长度 - 使用Kaiser窗经验公式 % Δf 是过渡带宽这里取 0.1 * Fc_norm delta_f 0.1 * Fc_norm; beta kaiser_beta(Astop); % 自定义函数查表得Kaiser窗β值 L_est ceil((Astop - 7.95) / (2.285 * 2*pi*delta_f)); L 2*floor(L_est/2) 1; % 强制奇数长度 % 3. 设计线性相位FIR滤波器 h_proto fir1(L-1, Fc_norm, low, kaiser(L, beta), noscale); % 4. 关键验证检查线性相位和阻带衰减 if ~islinphase(h_proto) error(Prototype filter is not linear phase!); end [H, w] freqz(h_proto, 1, 1024, whole); H_mag abs(H); % 找到阻带起始点通常在 Fc_norm*1.2 到 0.5 之间 idx_stop find(w 1.2*Fc_norm w 0.5, 1, first); if idx_stop min(H_mag(idx_stop:end)) 10^(-Astop/20) warning(Stopband attenuation may not meet requirement.); end end function beta kaiser_beta(Astop) % Kaiser窗β值查表法 if Astop 21, beta 0; elseif Astop 50, beta 0.5842*(Astop-21)^0.4 0.07886*(Astop-21); else, beta 0.1102*(Astop-8.7); end end这段代码的价值不在于它多炫酷而在于它把所有隐含的工程约束都显式化了。比如L的奇数强制就是为线性相位服务freqz后的验证是为了防止fir1在某些边界条件下失效。这些都是我在调试某款军用跳频电台时连续三天没睡才踩出来的坑。2.2 多相分解把一个长滤波器拆成M个短滤波器的“分治术”有了原型滤波器h_proto下一步就是多相分解。这步看似简单实则最容易出错。核心公式是$$ E_k[n] h_{proto}[nM k], \quad k 0, 1, ..., M-1 $$意思是把原型滤波器的所有系数按索引n对M取余分成M组。第k组的第n个系数就是原型滤波器中索引为n*Mk的那个系数。注意这里的索引n是从0开始的而Matlab数组索引从1开始所以实际编程时要加1。一个常见的致命错误是认为多相分量的长度就是ceil(L/M)。这是错的正确长度是floor((L-1)/M) 1。因为原型滤波器长度L可能不是M的整数倍。例如L129,M64那么k0组的索引是0,64,128共3个点k1组是1,65共2个点。所以各组长度并不完全相等。Matlab里必须用cell数组来存储不能用固定大小的矩阵。下面是我写的鲁棒性多相分解函数function E polyphase_decompose(h_proto, M) % h_proto: 原型滤波器系数列向量 % M: 信道数 % E: cell array, E{k} is the k-th polyphase component (k1..M) L length(h_proto); E cell(M, 1); for k 0:M-1 % 找出所有满足 n*M k L 的 n % 即 n (L - k)/M, 所以 n_max floor((L - k - 1)/M) n_max floor((L - k - 1)/M); if n_max 0 indices k : M : (n_max*M k); % Matlab索引从1开始所以k要1 E{k1} h_proto(indices 1); % 1 for 1-based indexing else E{k1} zeros(0, 1); % empty vector end end end这个函数的关键在于indices k : M : (n_max*M k)这一行。它直接生成了所有需要提取的索引避免了用for循环逐个判断的低效做法。而且它明确处理了L不是M倍数的情况确保每个E{k}的长度都是正确的。我曾经因为忽略了这一点在FPGA实现时发现第63路信道的滤波器输出总是零——就是因为k63时indices计算错误导致提取了一个空数组。2.3 DFT调制与IDFT合成多相滤波器银行的“灵魂”所在多相分解只是第一步真正的魔法在于如何把这些子滤波器组织起来形成一个高效的滤波器银行。这里有两个核心操作DFT调制用于发射机和IDFT合成用于接收机。发射机Channelizer输入是单路宽带信号x[n]。首先它被M路并行的多相子滤波器E_k[n]处理得到M路中间序列v_k[m]。然后对这M路序列进行M点DFT得到Y_k[l]这就是第k个子信道的复包络。最后Y_k[l]被上变频到各自的中心频率。这个过程的数学本质是把x[n]与一个复指数序列e^(-j2πkn/M)相乘后再滤波而DFT正是实现这种频谱搬移的最高效方式。接收机Dechannelizer过程正好相反。M路子信道信号Y_k[l]先进行M点IDFT得到v_k[m]再分别通过E_k[n]滤波最后将M路输出相加重建原始宽带信号x[n]。在Matlab里DFT/IDFT就是fft和ifft。但要注意为了保证能量守恒和数值稳定性IDFT后必须除以M。这是一个极易被忽略的缩放因子会导致接收机输出幅度错误甚至溢出。下面是一个完整的、可验证的多相信道化发射机核心模块function Y polyphase_channelizer(x, E, M) % x: 输入宽带信号列向量 % E: 多相分量cell array, E{k} for k1..M % M: 信道数 % Y: M x N matrix, each row is one subchannels complex envelope N length(x); % Step 1: Polyphase filtering - M parallel filters v cell(M, 1); for k 1:M % Each E{k} is a FIR filter, apply it to x v{k} filter(E{k}, 1, x); % Downsample by M: keep every M-th sample starting from index k % Because of the polyphase structure, v{k} has same length as x % So we take v{k}(k:M:end) v{k} v{k}(k:M:end); end % Step 2: DFT modulation % Pad each v{k} to same length for matrix operation max_len max(cellfun(length, v)); V_mat zeros(M, max_len); for k 1:M len_vk length(v{k}); V_mat(k, 1:len_vk) v{k}; end % Apply M-point DFT to each column (each time index) Y fft(V_mat, M, 1); % dim1 means DFT along rows % Optional: Normalize for energy conservation % Y Y / sqrt(M); end这段代码的精妙之处在于V_mat的构建。它把M路不同长度的v{k}统一填充到一个M x max_len的矩阵里然后用fft(..., M, 1)对每一列即每一个时间点上的M路信号做M点DFT。这比用for循环对每一列单独fft快得多也更符合Matlab的向量化精神。Y的每一行就是对应子信道的复包络可以直接送入后续的QAM调制器。3. 信道化发射机的Matlab实战从零搭建、逐层验证、避坑指南光有理论推导还不够必须把它变成可运行、可调试、可验证的Matlab代码。这一节我将手把手带你搭建一个完整的64路信道化发射机并分享那些只有在深夜调试时才会浮现的、教科书里绝不会写的避坑指南。3.1 系统参数设定与信号源生成一个“真实”的测试场景任何通信系统的验证都始于一个足够“真实”的测试信号。我从来不用简单的sinc或randn而是模拟一个典型的宽带OFDM信号。这样既能检验信道化器的频率选择性又能暴露相位响应问题。%% 1. 系统参数 M 64; % 信道数 Fs 128e6; % 原始采样率 128 MHz Fc Fs/2; % 中心频率即基带 % 为简化我们工作在基带所有频率都是归一化的 %% 2. 生成测试信号一个64-QAM OFDM帧 N_fft 512; % OFDM FFT size N_cp 64; % 循环前缀长度 N_sym 10; % 符号数 % 生成随机QAM符号 data_bits randi([0, 1], 6*N_fft, 1); % 64-QAM, 6 bits per symbol qam_symbols qammod(data_bits, 64, UnitAveragePower, true); % 构造OFDM帧 x_ofdm []; for sym_idx 1:N_sym % 将符号映射到子载波这里用全部512个子载波模拟满带宽 X zeros(N_fft, 1); X(2:end-1) qam_symbols((sym_idx-1)*N_fft1:sym_idx*N_fft); % IFFT x_time ifft(X) * sqrt(N_fft); % 能量归一化 % 添加循环前缀 x_cp x_time(end-N_cp1:end); x_sym [x_cp; x_time]; x_ofdm [x_ofdm; x_sym]; end % 此时 x_ofdm 是一个很长的列向量代表时域OFDM信号 % 它的带宽理论上是 Fs/N_fft 250 kHz但经过升采样后会扩展 % 我们将用它来测试信道化器的带宽分割能力这个测试信号的价值在于它包含了丰富的频谱成分和严格的相位关系。如果信道化器的群延迟不平坦你在某个子信道里看到的星座图就会严重旋转和扩散。这比用白噪声测试能更快地暴露问题。3.2 多相滤波器银行的搭建与初始化现在我们调用前面设计的函数生成原型滤波器和多相分量。%% 3. 设计原型滤波器和多相分量 Astop 65; % 阻带衰减 65 dB h_proto design_prototype_filter(M, Fs, Astop); E polyphase_decompose(h_proto, M); % 验证多相分量 fprintf(Prototype filter length: %d\n, length(h_proto)); for k 1:M fprintf(E{%d} length: %d\n, k, length(E{k})); end % 你应该看到大部分E{k}长度相同少数通常是最后几个会少1个点这里有一个关键的“眼见为实”验证步骤画出所有E{k}的时域波形和频域响应。我习惯用一个2x32的子图来展示前64个分量虽然M64但为了清晰只画前32个。figure; for k 1:min(32, M) subplot(2, 32, k); stem(E{k}, filled); title(sprintf(E{%d}, k)); ylim([-max(abs([E{:}]))*1.1, max(abs([E{:}]))*1.1]); if k 1, ylabel(Amplitude); end end for k 1:min(32, M) subplot(2, 32, k32); [H, w] freqz(E{k}, 1, 512); plot(w/pi, 20*log10(abs(H)eps)); title(sprintf(|H_{%d}(f)|, k)); xlabel(Normalized Freq); ylabel(Magnitude (dB)); ylim([-100, 5]); end这张图会让你直观地看到所有E{k}的频响形状都高度相似只是相位有微小差异。这正是多相结构的特征——它们共享同一个原型滤波器的“基因”只是在时间轴上做了平移。如果你看到某几个E{k}的频响突然变得很窄或很宽那一定是多相分解的索引算错了。3.3 发射机核心流程信道化、频谱搬移与功率归一化现在把x_ofdm喂给polyphase_channelizer函数。%% 4. 执行信道化 Y polyphase_channelizer(x_ofdm, E, M); % Y 是 M x N_y 的矩阵N_y 是子信道信号的长度 % 每一行 Y(k,:) 就是第k个子信道的复包络 N_y size(Y, 2); % 验证检查各子信道的能量 energy_per_ch sum(abs(Y).^2, 2); figure; stem(1:M, 20*log10(energy_per_ch/max(energy_per_ch)eps)); xlabel(Channel Index); ylabel(Relative Power (dB)); title(Power Distribution Across Channels); grid on;这张功率分布图应该是非常平坦的波动不超过±0.5dB。如果出现明显起伏说明多相滤波器的幅度响应不平坦或者DFT调制引入了泄漏。这时你需要回溯到原型滤波器设计检查Fc_norm是否设置正确或者尝试增加滤波器长度L。接下来是信道化发射机的最后一步将每个子信道的复包络Y(k,:)上变频到各自的中心频率。在Matlab里这很简单%% 5. 上变频到各子信道中心频率 % 子信道中心频率f_k (k - M/2) * (Fs/M), for k1..M % 归一化频率f_k_norm (k - M/2) / M x_tx zeros(length(x_ofdm), 1); % 初始化发射信号 for k 1:M f_k_norm (k - M/2) / M; % 归一化中心频率 % 生成复指数载波 t_vec (0:N_y-1); carrier exp(1j * 2 * pi * f_k_norm * t_vec); % 上变频 y_k_up Y(k, :).* carrier; % 注意y_k_up 是复信号我们需要将其转换为实信号I/Q % 这里我们直接取实部作为发射信号的一部分简化模型 % 实际系统中会用DAC输出I和Q两路 x_tx_k real(y_k_up); % 将其加到总发射信号上注意长度对齐 % 因为Y(k,:)是下采样后的长度N_y而x_ofdm长度是N % 所以需要插值回原始速率 if N_y length(x_ofdm) x_tx_k_full interp1(1:N_y, x_tx_k, linspace(1, N_y, length(x_ofdm)), linear, extrap); else x_tx_k_full x_tx_k(1:length(x_ofdm)); end x_tx x_tx x_tx_k_full; end % 最后对总发射信号做功率归一化 x_tx x_tx / max(abs(x_tx));这段代码里藏着两个重要经验插值对齐Y(k,:)的长度N_y是x_ofdm长度的1/M所以在上变频后必须用interp1将其插值回原始采样率。我用的是线性插值对于大多数通信场景已足够。如果对频谱纯度要求极高可以用sinc插值但计算量会大增。功率归一化x_tx是M路信号的叠加其峰值功率会远高于单路。如果不归一化后续的DAC会饱和。x_tx x_tx / max(abs(x_tx))这行是保证信号动态范围在[-1,1]内的最后一道防线。3.4 避坑指南那些让我熬了三个通宵的“幽灵Bug”在搭建这个发射机的过程中我遇到了几个极其隐蔽的Bug它们不会让程序报错但会让整个系统在实测中完全失效。我把它们记录下来希望你能绕开这些坑。提示第一个幽灵Bug——多相分解的索引偏移在polyphase_decompose函数里indices k : M : (n_max*M k)这行k是0-based而Matlab索引是1-based。所以提取时必须h_proto(indices 1)。我最初忘了1导致所有E{k}都错了一位。症状是频谱看起来没问题但解调出来的星座图完全散开BER高达50%。花了两天时间我才用debug模式单步跟踪发现E{1}的第一个系数竟然是h_proto(2)而不是h_proto(1)。提示第二个幽灵Bug——DFT调制的相位旋转fft(V_mat, M, 1)的结果其相位是相对于n0时刻定义的。但在信道化系统中由于多相滤波器的群延迟v_k[m]的起始时间点并不是对齐的。这会导致Y(k,:)的相位有一个随k线性变化的旋转项。如果不补偿各子信道的载波相位就不一致。解决方案是在DFT之后对每一行Y(k,:)乘以一个补偿因子exp(-1j*2*pi*(k-1)*(D/M))其中D是原型滤波器的群延迟约为L/2。这个补偿项在comm.Channelizer的底层是自动做的但自己写就必须手动加。提示第三个幽灵Bug——浮点精度累积误差当M很大如256时fft和filter的多次运算会引入显著的浮点误差。特别是在接收机的IDFT合成环节误差会被放大。我的解决办法是在polyphase_channelizer和polyphase_dechannelizer的最后都加入Y round(Y * 1e6) / 1e6这样的量化步骤把精度控制在1e-6量级。这在Matlab仿真中是安全的因为实际ADC的分辨率也就12-14 bit。4. 信道化接收机的Matlab实现IDFT合成、多相滤波与信号重建如果说发射机是“分而治之”那么接收机就是“合而为一”。它的任务是将M路并行的、已下变频的子信道信号无失真地重建为原始的宽带信号。这个过程比发射机更脆弱因为任何微小的失配都会在合成时被放大。4.1 接收机架构解析为什么IDFT合成是“不可替代”的接收机的结构是发射机的严格逆过程。但这里有个关键区别在发射端DFT调制是“主动”的频谱搬移而在接收端IDFT合成是“被动”的频谱重组。它的数学基础是离散傅里叶变换的正交性。假设发射端输出的M路子信道信号为Y_k[l]接收端收到的也是Y_k[l]忽略信道损伤。那么IDFT合成的输出z[n]为$$ z[n] \frac{1}{M} \sum_{k0}^{M-1} Y_k[\lfloor n/M \rfloor] \cdot e^{j2\pi kn/M} $$这个公式揭示了IDFT合成的两个核心作用频谱对齐e^{j2\pi kn/M}这个复指数把每个子信道的基带信号精确地搬回到它在原始频谱中的位置。能量汇聚求和操作把分散在M个子信道中的能量重新汇聚到z[n]的每一个样本点上。如果跳过IDFT直接用M个独立的滤波器去处理Y_k[l]你会发现重建的信号z[n]充满了严重的频谱混叠和相位失真。因为Y_k[l]本身是下采样后的信号其奈奎斯特带宽只有Fs/M直接滤波无法恢复原始的Fs带宽。IDFT是唯一能将M个窄带信号在时域上精确“编织”成一个宽带信号的数学工具。4.2 IDFT合成与多相滤波的联合实现下面是一个鲁棒的polyphase_dechannelizer函数它完成了IDFT合成和多相滤波的联合操作。function x_rec polyphase_dechannelizer(Y, E, M, N_orig) % Y: M x N_y matrix, each row is one subchannels complex envelope % E: 多相分量cell array % M: 信道数 % N_orig: 原始信号长度用于确定输出大小 N_y size(Y, 2); % Step 1: IDFT synthesis % Y is M x N_y, so we do M-point IDFT on each column V_mat ifft(Y, M, 1); % dim1 means IDFT along rows % Normalize by M for energy conservation V_mat V_mat / M; % V_mat is now M x N_y, where each column is the time-domain output % of the IDFT for that time index % Step 2: Polyphase filtering and summation % For each time index m (column of V_mat), we have M values v_k[m] % We need to filter each v_k[m] with E{k} and sum them up % But note: v_k[m] is already the output of the IDFT, so its at rate Fs/M % We need to upsample it back to Fs before filtering? No! % In polyphase structure, the filtering is done at the low rate. % So we apply filter E{k} to the sequence v_k[1], v_k[2], ..., v_k[N_y] % Then upsample the result by M, and sum all M upsampled sequences. x_rec zeros(N_orig, 1); for k 1:M % Filter v_k with E{k} v_k_filtered filter(E{k}, 1, V_mat(k, :)); % Upsample by M: insert M-1 zeros between each sample v_k_up zeros(M * length(v_k_filtered), 1); v_k_up(1:M:end) v_k_filtered; % Now, v_k_up has length M*N_y, but we only need first N_orig samples len_to_add min(length(v_k_up), N_orig); x_rec(1:len_to_add) x_rec(1:len_to_add) v_k_up(1:len_to_add); end % Optional: Normalize for overall gain % The total gain of the channelizer/dechannelizer pair should be ~1 % You can measure it with a known input and adjust here x_rec x_rec / max(abs(x_rec) eps); end这个函数的逻辑链条非常清晰先对Y做M点IDFT得到V_mat并除以M归一化。然后对V_mat的每一行即v_k[m]序列用对应的E{k}滤波。滤波后的序列v_k_filtered长度为N_y。接着用zeros和索引的方式实现M倍插值上采样即在每两个样本间插入M-1个零。最后把M路插值后的信号在时域上逐点相加得到重建信号x_rec。这里的关键洞察是多相滤波器的输出本身就是上采样后的结果。E{k}的滤波操作天然地完成了插值滤波的功能。所以我们不需要像传统方法那样先插值再滤波而是直接用E{k}对低速率的v_k[m]滤波其输出就等效于“插值滤波”后的信号。4.3 端到端验证用OFDM信号测试重建保真度现在我们用前面生成的x_ofdm作为输入经过发射机得到Y再经过接收机得到x_rec最后对比两者。%% 6. 端到端测试 % 假设我们已经有了 Y 从发射机得到 % 现在用它来驱动接收机 x_rec polyphase_dechannelizer(Y, E, M, length(x_ofdm)); % 计算重建误差 error_signal x_ofdm - x_rec(1:length(x_ofdm)); mse mean(abs(error_signal).^2); snr_db 10*log10(mean(abs(x_ofdm).^2) / mse); fprintf(End-to-End SNR: %.2f dB\n, snr_db); % 画出时域对比 figure; subplot(2,1,1); plot(real(x_ofdm( p a hrefhttps://download.csdn.net/download/vvoennvv/88410042 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