ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

数字基带传输系统仿真:Simulink建模、升余弦滤波与BER曲线验证

数字基带传输系统仿真:Simulink建模、升余弦滤波与BER曲线验证 简介基于 Matlab/Simulink 的数字基带传输系统仿真文档适合通信工程和电子信息类专业学生、课程设计者及科研人员用以掌握数字基带信号的编码、传输与误码性能分析。文档从数字基带传输系统的基本概念切入详细说明 AMI、HDB3、双相码、CMI 等码型的原理与适用场景并基于 Simulink 的可视化建模环境完成发送/接收滤波器、时钟恢复、位定时提取等核心模块的设计与联调。通过仿真可得到基带波形和误码率曲线并与理想双极性系统进行对比结果基本吻合验证了仿真模型的正确性。整套资源打包为单个 docx 文档大小约 786KB结构涵盖系统概述、仿真模型构造、实验设计与结果分析等章节便于按步骤阅读和复用。已有 266 人学习既可以作为通信原理课程设计、数字通信仿真实习的参考也可供教师备课和科研人员快速搭建数字基带仿真模型使用。1. 数字基带传输系统仿真从波形到误码率的完整闭环数字基带传输系统是所有通信系统仿真里最容易被低估的一环。很多人直接跳过基带一上来就搭 QPSK、OFDM 的高频链路结果接收端波形发散、误码率曲线对不上理论值回头排查才发现是基带的采样率、滤波器滚降系数和抽样判决时刻没有对齐。用 MATLAB/Simulink 做数字基带传输系统仿真本质是把「信源 → 码型变换 → 发送滤波 → 信道 → 接收滤波 → 抽样判决 → 误码统计」这条链路在离散时间域里复现一遍难点不在 Simulink 操作而在每个模块的采样时间、延迟和数据类型是否一致。本文适合两类人一类是刚接触通信仿真、想用 Simulink 把教材上的基带理论跑通的学生另一类是做 FPGA 或软件无线电、需要先验证基带算法再落硬件的工程师。前者能照着步骤搭出可运行的模型后者能直接复用里面的参数配置和脚本验证方法。2. 数字基带传输的理论边界与噪声模型选择2.1 NRZ/RZ 波形与功率谱密度的关系数字基带信号最常见的两种码型是单极性 NRZ 和双极性 NRZ。单极性 NRZ 在 1 时输出高电平、0 时输出 0频谱中包含离散的直流分量和时钟分量双极性 NRZ 在 1 时输出正电平、0 时输出负电平频谱中没有离散谱线功率集中在低频段。这个差异直接决定了 Simulink 模型里信道的直流偏置处理方式——单极性 NRZ 经过隔直电容后会引入基线漂移而双极性 NRZ 不会。在 Simulink 里生成 NRZ 波形不能用简单的 Step 信号拼接而是要基于随机整数源和采样保持。常见做法是用 Bernoulli Binary Generator 产生 0/1 序列再经过一个 Gain 和 Bias 的组合把 0/1 映射成 -1/1。映射关系可以用一个查表模块替代但 GainBias 更直观参数也更容易回读。% 在 MATLAB 脚本中预计算双极性 NRZ 的功率谱用于和 Simulink 结果对比 fs 1000; % 采样率 Hz Tb 0.01; % 码元宽度 s t 0:1/fs:Tb*100; % 100 个码元的时长 data randi([0 1], 1, 100); nrz 2*data - 1; % 双极性映射 nrz_up reshape(repmat(nrz, length(t)/100, 1), [], 1); [pxx, f] pwelch(nrz_up, hamming(256), 128, 512, fs); plot(f, 10*log10(pxx)); grid on; xlabel(频率 Hz); ylabel(功率谱密度 dB/Hz); title(双极性 NRZ 功率谱);这段代码里最关键的是repmat之后的reshape方向。如果维度写反得到的是按列填充的矩阵转置后的一维数组波形会在码元切换点出现毛刺。pwelch的窗长取 256、重叠 128、FFT 点数 512是通信仿真里比较常规的一组参数窗长太短频谱会过度平滑滚降特性看不出来。2.2 码间串扰与升余弦滚降滤波数字基带传输系统仿真的核心矛盾是带宽受限带来的码间串扰。理论上奈奎斯特第一准则告诉我们可以用带宽为 Rb/2 的理想低通滤波器做到无码间串扰但理想低通的冲击响应衰减慢定时抖动下会迅速恶化。工程上普遍选择升余弦滚降滤波器用多余的带宽换取对抽样时刻偏差的容忍。升余弦滤波器在 Simulink 里有两个层面的实现一是用 Raised Cosine Transmit Filter 模块做脉冲成形二是用 MATLAB 里的rcosdesign函数离线生成系数再导入 FIR 模块。我的建议是优先用rcosdesign配合 Discrete FIR Filter因为这样你能直接控制滤波器阶数和量化位宽下游做 FPGA 定点仿真时可以直接复用系数文件。span 10; % 滤波器覆盖的码元个数 rolloff 0.5; % 滚降系数越大带宽越宽波形越平缓 sps 8; % 每码元采样点数必须是整数且大于 2 h rcosdesign(rolloff, span, sps, sqrt); % 根升余弦收发各用一半 fprintf(滤波器长度 %d, 归一化带宽 %.2f Hz\n, length(h), (1rolloff)/2);这里的sqrt参数值得强调。如果发送端和接收端各自用一个根升余弦滤波器级联后的响应等效为一个完整的升余弦滤波器总带宽正好是 (1rolloff)/2 倍码元速率。很多人直接在链路里放两个完整升余弦滤波器结果是等效带宽更窄眼图张开度变小误码率比理论值偏高。滚降系数取 0.350.5 在仿真里最稳妥取 0 时滤波器长度不变但时域拖尾严重抽样位置偏离一点就会出现明显 ISI。2.3 AWGN 信道与信噪比定义Simulink 的 AWGN Channel 模块里有两种 SNR 定义方式按 Eb/No 或按 Es/No。对数字基带传输系统误码率理论曲线通常是关于 Eb/No 的函数双极性 NRZ 在匹配滤波下的误码率是 Q(sqrt(2*Eb/No))。用 AWGN Channel 模块时要把输入端口的信号功率先测量出来再设置 SNR(dB)因为模块默认按输入信号功率计算噪声方差。测量信号功率最简单的方法是在发送滤波器输出后接一个 Display 模块同时将仿真时间设成整数个码元的整数倍让平均值窗口恰好覆盖完整的码元周期。信号功率测量不准是 BER 曲线偏移的主要原因比滤波器参数错误更难排查。% 计算给定 Eb/No 下双极性 NRZ 的理论误码率 EbNo_dB 0:2:12; EbNo_lin 10.^(EbNo_dB/10); Pe erfc(sqrt(EbNo_lin)) / 2; % 注意不乘 2双极性 PAM 的公式 semilogy(EbNo_dB, Pe, b-o); grid on; xlabel(Eb/No (dB)); ylabel(误码率); title(双极性 NRZ 理论误码率);这里用erfc而不是qfunc是因为erfc在 MATLAB 基础工具箱里就有而qfunc需要 Communications Toolbox。注意公式里没有乘以 2很多教材里写成 P Q(sqrt(2Eb/N0))对应的是双极性信号在匹配滤波后的误码率乘以 2 是单极性或 OOK 的近似。3. 用 Simulink 搭建数字基带传输链路的最小可运行模型3.1 信号源与并串转换的设置打开 Simulink 空白模型从 Communications Toolbox 里拖入 Bernoulli Binary Generator。核心参数有三个Probability of a zero 默认 0.5Sample time 设为码元周期的整数倍Samples per frame 决定一次输出多少个码元。这里有一个容易踩的坑如果把 Sample time 直接设为码元周期 Tb那么后面的脉冲成形滤波器必须设置为每码元多个采样点否则滤波器输出速率不足无法生成平滑的基带波形。常用做法是让信号源按每个码元输出一个样本然后在发送滤波器里通过插值实现上采样。Raised Cosine Transmit Filter 模块的 Input samples per symbol 设为 1Output samples per symbol 设为 8滤波器内部会自动完成插值。如果你想让信号源直接输出每码元 8 个样本也不是不行但要额外在滤波器前加一个 Downsample 模块处理不好会引入相位偏置。块与块之间的采样率关系可以通过菜单 Display → Signals Ports 里的 Sample Time Legend 查看红色表示连续信号彩色数字表示离散采样率。并串转换在纯基带仿真里其实可以省略。只有当你要把多路并行数据变成一路串行码流时才用 Parallel to Serial Converter 模块它的 Block size 参数要和上游帧长度匹配。帧长度的不匹配会导致数据错位现象很隐蔽——眼图正常星座图正常但误码率一直停留在 0.5 左右。遇到这种情况先检查每条信号线的 Sample Time 标注再看每个模块的帧长度。3.2 升余弦发送滤波器与抽样判决模块配置发送端用 Raised Cosine Transmit Filter关键参数是 Filter span in symbols建议 10、Roll-off factor建议 0.35、Output samples per symbol建议 8。滤波器系数量化位宽默认是全精度如果后续要接定点链路可以在 Filter coefficients 里勾选 Inherit via internal rule但这会改变滤波器响应BER 曲线会有约 0.1 dB 的损失属于正常现象。接收端用一个相匹配的 Raised Cosine Receive Filter参数必须与发送端完全一致。两个滤波器级联后眼图在最佳抽样点附近会非常清晰。抽样判决用 General Block Deinterleaver 不一定合适更直接的方式是 Manual Switch 配合 Triggered Subsystem但最稳定的方案是直接用 Error Rate Calculation 模块内部自带的延迟对齐功能它内部会做数据对齐不需要手动找最佳抽样时刻。我通常会在接收滤波器后加一个 Scope 看波形并且把 Scope 的 Sampling 模式设为 Decimation值设成 8这样 Scope 上每 8 个点显示一个点等效于在码元中心抽样。如果 Decimation 值不对Scope 上看到的就是一个密实的波形带点开之后也看不出眼图的张开度。3.3 用误码率统计模块验证理论曲线链路最后接 Error Rate Calculation 模块Rx 端口接判决后的数据Tx 端口接延迟对齐后的原始数据。模块内部会输出三个量误码率、错误比特数、总比特数。关键参数是 Receive delay这个值必须等于发送滤波器群延迟和接收滤波器群延迟之和单位是码元周期还是样本周期取决于模块文档。实际调试时不要手工数延迟用 Error Rate Calculation 模块自带的自适应延迟即可勾选 Output data 里的 BER 端口然后在 MATLAB 脚本里循环设置 SNR 值跑仿真。% 批跑 BER 曲线的核心循环代码 EbNo_dB 0:2:12; ber_sim zeros(size(EbNo_dB)); for k 1:length(EbNo_dB) set_param(baseband_model/AWGN Channel, EbNo, num2str(EbNo_dB(k))); out sim(baseband_model, StopTime, 1e5); ber_sim(k) out.BER(end); % 取最后一次统计结果 end semilogy(EbNo_dB, ber_sim, r-*); hold on; % 叠加理论曲线代码见 2.3 节set_param里的模块路径要和你模型里的名字完全一致包括空格大小写。仿真停止时间设成 1e5 个码元BER 在 1e-3 量级时大约有 100 个错误比特统计波动已经小于 10%如果只跑到 1e4 码元BER 曲线会上下跳动误以为是信道模型问题其实只是样本量不足。4. 仿真步长、缓冲区与随机种子让 BER 曲线稳定收敛4.1 采样时间与传输速率的整数倍约束数字基带传输系统的每个离散模块都有自己的采样时间Simulink 在仿真开始前不会强制你统一但运行时会产生速率转换警告。最基础也是最重要的规则是所有码元速率必须是整数关系。信号源 Sample time 1滤波器 Input samples per symbol 1Output samples per symbol 8此时滤波器的输出采样时间是 1/8。后面 AWGN 模块和误码率模块的采样时间必须是 1/8不能设置成 1/7 或 0.12 这种非整数。在离散模型中设置离散时间步长时建议在 Configuration Parameters → Solver 里把 Type 设为 Fixed-stepFixed-step size 设为 autoSolver 选 discrete (no continuous states)。很多用户直接把 Solver 留默认的变步长 ode45模型里没有连续状态时它也能跑但缓冲区管理和 Scope 刷新会不稳定BER 统计模块可能漏记数据。固定步长配合离散求解器是通信仿真的标准配置可以避免仿真发散这类问题。仿真步长与滤波器采样周期不匹配时滤波器输出的波形会出现锯齿状抖动。排查方法是在接收滤波器的输出线上用 Probe 模块读取采样时间如果显示的值和滤波器 Output samples per symbol 设置不符说明有隐式的 Zero-Order Hold 或 Rate Transition 插入了链路。Rate Transition 本身不坏但它的 Output port initial conditions 可能导致前几个码元数据损坏影响 BER 统计。4.2 显示缓冲区与信号属性检查Scope 模块的默认缓冲是 5000 个点如果你查看的信号采样率是码元速率的 8 倍一个屏只能显示 625 个码元而 BER 统计需要的数据量是 1e5 量级。两种解法一是把 Scope 的 History 标签里的 Limit data points to last 改为 Unlimited二是用 To Workspace 模块把波形导出在 MATLAB 里用plot查看。用 To Workspace 时有几个参数要小心。Variable name 里不能带点号Save format 建议选 Timeseries这样输出对象的Time属性里能拿到每个样本的绝对时间方便后续计算延迟。如果选 ArraySimulink 会直接把采样时间列去掉你还要额外记录步长很麻烦。% 读取 To Workspace 导出的接收波形并手动抽取最佳抽样点 rx out.rx_signal.Data; % TimeSeries 数据 t out.rx_signal.Time; Tb 1; % 码元周期和模型设置一致 sps 8; % 每码元采样点数 n_symbols floor(length(rx) / sps) - 20; % 去掉头部暂态 idx (10*sps1) : sps : (10n_symbols)*sps; % 从第 10 个码元起抽 sampled rx(idx); scatter(1:n_symbols, sampled, 5, filled); grid on;头部暂态是必须去掉的。滤波器群延迟大约为 span/2 5 个码元前 5 个码元的输出是滤波器卷积窗口未填满时的部分响应直接参与 BER 统计会引入系统性的偏差。这里的10*sps1多给了 5 个码元的裕量数据充足时建议直接扔掉前 20 个码元。4.3 随机种子与蒙特卡洛重复运行AWGN Channel 模块和 Bernoulli Binary Generator 模块都有随机种子参数。默认情况下每次仿真生成的噪声和信源码都不同导致你在调参时无法判断效果改善是来自参数修改还是随机波动。固定种子的做法是在 Bernoulli Binary Generator 的 Source of initial seed 里选 Parameter输入一个固定值比如 37AWGN Channel 的 Random seed 也设成固定值。这样每次跑同样的参数组合输出 BIT EXACT 一致。固定种子之后要评估一条 BER 曲线的稳定性合理做法是保持信噪比不变、只改变噪声种子重复跑 10 次把错误比特数的均值和方差记录下来。错误比特数近似服从泊松分布方差约等于均值因此当错误比特数大于 100 时相对误差小于 10%可以接受。种子的选取只需要保证不同 Eb/No 点之间不重复不要用相同的噪声种子跑整条 BER 曲线否则曲线会在同一 Eb/No 处出现关联性跳变。5. 眼图、星座图与 MATLAB 脚本联合验证5.1 Eye Diagram Scope 的触发与余晖设置Simulink 里没有单独的叫 Eye Diagram 的模块正确名称是 Communications Toolbox 里的 Eye Diagram Scope。双击打开后在 Display 选项卡里设置 Samples per symbol 为 8Symbols per trace 为 2Traces 为 300。余晖时间设置很关键余晖太短眼图只显示最近几十个码元轮廓模糊余晖太长显示刷新非常慢调参数时反馈延迟大到不可接受。经验值是设成 23 秒。触发位置决定眼图的水平对齐质量。Eye Diagram Scope 默认用第一个输入的上升沿作为触发如果接收滤波器的输出带有直流偏置触发点会抖动。要在 Display 菜单里把 Trigger offset 设成最佳抽样时刻对应的相对位置对根升余弦滤波器加匹配滤波器的情况这个值通常在码元周期的中点附近。% 用离线方式画出眼图效果与 Scope 等价且可保存 rx out.rx_signal.Data; sps 8; len floor(length(rx)/sps) * sps; rx rx(1:len); rx_mat reshape(rx, sps, []); % 每个码元画一条线绘制多个码元叠加 n_traces size(rx_mat, 2) - 1; tt (0:sps-1) / sps; figure; hold on; for k 1:200 % 只画 200 个码元避免线条过密 plot(tt, rx_mat(:, k), b-, LineWidth, 0.5); end xlabel(码元周期内相对时间); ylabel(幅度); title(sprintf(接收信号眼图 (滚降系数 %.2f), 0.35));每次画 200 条线是为了让眼睛能分辨出轨迹密度。如果一次性画出几千条线中间轨迹会叠加成一片纯黑色看不出眼图的张开度。另外注意要把rx_mat的列数不足 200 的尾部裁掉避免plot变长不齐。5.2 从 Simulink 导出数据到 MATLAB 做 BER 拟合BER 曲线跑完之后除了和理论公式对比还可以做一件事用最小二乘拟合验证仿真结果的斜率是否与理论一致。理论误码率在误码率较小时近似指数衰减把 BER 取对数后对 Eb/No 做线性回归斜率接近 -1 时说明模型正确斜率偏差超过 20% 时说明卷积码或滤波器参数有误。EbNo_dB 0:2:12; ber_sim [0.18, 0.08, 0.025, 0.006, 0.001, 0.0002, 0.00003]; % 示例数据 % 取误码率大于 1e-5 的点做线性拟合 idx ber_sim 1e-5; p polyfit(EbNo_dB(idx), log10(ber_sim(idx)), 1); fprintf(斜率 %.2f dB/decade\n, p(1));有两点要提醒。第一拟合时要去掉 Eb/No 过低的数据点0 dB 附近理论曲线不在指数衰减区拟合斜率虚高。第二BER 仿真数据里若有 0 值比如高信噪比时 1e5 个码元一个误码都没出现log10 会给出 -Inf直接把这类点剔除不要让它参与拟合。纯基带仿真做到这一步已经具备完整的验证闭环波形、眼图、BER 曲线三向印证接下来无论是换调制方式、加均衡器还是改成定点模型做 FPGA 实现这个模型都可以作为基准链路继续扩展。最后一件事是养成保存时把随机种子和仿真步长写进模型描述的习惯Simulink 模型的回调函数里加一行disp([Eb/No , num2str(EbNo)])这样回读模型时你能立刻知道这组仿真是什么条件下产生的。本文还有配套的精品资源点击获取
返回列表