基于MATLAB的2FSK数字通信系统设计:调制解调、高斯白噪声与误码率 简介这份基于 MATLAB 的 2FSK 数字通信系统设计文档面向通信工程、电子信息类专业学生以及正在完成通信原理课程设计、数字调制仿真练习的读者。内容围绕频移键控的调制与解调展开从课程设计目的、任务内容与设计原理讲起逐步给出 2FSK 信号的时域表达式、键控法产生思路、相干解调与抽样判决流程并借助 MATLAB 与 Simulink 环境完成建模验证。文中包含 dmod 调制、awgn 加噪、误码率统计等关键代码片段可对照理解载频、采样频率、码速率、信噪比等参数设置对系统性能的影响也便于在课程设计报告中整理原理图、波形图与实验结果。压缩包为单一 PDF 文件共 1 个文件大小约 479KB阅读与打印都比较轻便。目前已有 788 人学习下载适合作课程设计参考、仿真入门案例与实验报告撰写的辅助材料。1. 为什么 2FSK 仿真值得动手跑一遍很多人学通信原理时2FSK 是被一句频率随基带信号在 f1、f2 之间切换带过的知识点考试能画波形真让你用代码从零搭一条链路往往卡在采样率与码速率的关系上。这份基于 MATLAB 的 2FSK 数字通信系统设计恰好把整条链路摊开随机码产生、键控调制、高斯白噪声信道、相干解调、抽样判决、误码率统计。它适合通信原理课程设计阶段的人也适合工作后想重温调制解调数值细节的人。它解决的问题很具体——把课本公式变成一段能跑、能画图、能看误码率的脚本。你不需要昂贵设备一台装了 MATLAB 的普通电脑就够。参数里藏着的坑也真实Fc、Fs、Fd 一旦不满足采样定理波形立刻失真SNR 的换算方式写错误码率曲线就会漂亮得可疑。下面按链路顺序把每一步的参数含义和排错方法讲透。2. 2FSK 调制原理与 MATLAB 参数建模2.1 两个 2ASK 叠加的时域本质2FSK 信号的时域表达式可以写成两个不同载频的 2ASK 信号之和这正是设计正文强调的那句二进制移频键控信号可以看成是两个不同载波的二进制振幅键控信号的叠加。设二进制基带序列为 $a_n$则$$e_{2FSK}(t)\left[\sum_n a_n g(t-nT_s)\right]\cos(2\pi f_1 t)\left[\sum_n \bar{a_n} g(t-nT_s)\right]\cos(2\pi f_2 t)$$其中 $a_n$ 为 1 时走 $f_1$ 支路为 0 时走 $f_2$ 支路$\bar{a_n}$ 是取反。理解这一点接收端用两路相干解调再比较抽样值就顺理成章了——本质上是两个 2ASK 解调器的并联。需要区分两种产生方式键控法电子开关在两个独立振荡源间切换相位不一定连续频率切换处会引入频谱展宽直接调频法相位连续但实现不同。这份设计用的是键控法在 MATLAB 里对应dmod的fsk模式相邻码元相位不连续这对后续带通滤波器的通带设计有直接影响。2.2 关键参数Fc、Fs、Fd、N 各自管什么设计里给出的初始化参数是整段代码的地基逐个拆开看参数取值含义设错后果Fc10载频与 df 一起决定 f1、f2 的绝对位置Fs40系统采样频率低于 2×最高频率即混叠Fd1码速率波特率决定码元宽度N Fs/Fd40每码元采样点数抽样判决的时基df10频率间隔f1、f2 的间距M2进制数2FSK 固定为 2numSymb25仿真码元数太少则误码率统计不稳采样定理给出的硬约束是最高频率分量必须小于 Fs/2。这里 f1、f2 大致落在 Fc±df/2 附近取 Fs40 相对 Fc10 有 4 倍余量安全。如果哪天把 Fc 提到 30 而 Fs 忘了改画出来的波形就会像糊掉的锯齿这是新手最常见的第一类坑。提示Fd 与 Fs 的比值 N 最好取整数非整数会让每码元采样点数抖动抽样判决时刻产生偏移误码率无故升高。2.3 生成随机二进制序列Fc 10; % 载频 Fs 40; % 系统采样频率需满足奈奎斯特采样定理 Fd 1; % 码速率 N Fs/Fd; % 每码元采样点数 df 10; % 两个载频的频率间隔 numSymb 25; % 仿真的信息码元个数 M 2; % 2FSK进制数为 2 SNRpBit 60; % 每比特信噪比(dB) SNR SNRpBit/log2(M); seed [12345 54321]; numPlot 25; % 产生 numSymb 个取值在 [0, M-1] 的随机整数即二进制随机码 x randsrc(numSymb, 1, [0:M-1]); figure(1) stem([0:numPlot-1], x(1:numPlot), bx); title(二进制随机序列); xlabel(Time); ylabel(Amplitude);randsrc(numSymb,1,[0:M-1])不带权重参数时[0,1] 等概率出现等价于公平的随机比特流。用randsrc而不是randi的原因是前者的第三参数可以指定符号集与对应概率方便以后扩展到非等概信源。stem比plot更适合画离散序列一眼能看出每个码元的取值。固定seed是为了让每次运行结果可复现调参时才有对照基准。3. 键控调制与高斯白噪声信道的代码实现3.1 用 dmod 完成 2FSK 调制% 调制M 元 FSK频率间隔为 df y dmod(x, Fc, Fd, Fs, fsk, M, df); numModPlot numPlot * Fs; % 25 个码元对应的总采样点数 t [0:numModPlot-1] ./ Fs; % 时间轴 figure(2) plot(t, y(1:length(t)), b-); axis([min(t) max(t) -1.5 1.5]); title(调制后的信号); xlabel(Time); ylabel(Amplitude);dmod的参数顺序是dmod(信号, 载频, 码速率, 采样率, 调制方式, 进制数, 频偏)。这里的fsk表示一般 M 元频移键控传M2即退化为 2FSK。关键在于df必须足够大两个载频间隔太近接收端带通滤波器无法分辨误码率会急剧恶化间隔太大又浪费带宽。常见经验是让 df 与 Fd 同量级本例 df10、Fd1带宽富余。频偏与载频如何共同决定 f1、f2取决于工具箱的具体定义多数情况下两个频率分别位于 Fc 上下各 df/2 处。想确认可以在调制后对信号做 FFT看频谱峰值落在哪两个频率上这比查手册更快。Y fft(y(1:numModPlot)); f (0:length(Y)-1) * Fs / length(Y); plot(f(1:floor(end/2)), abs(Y(1:floor(end/2)))); title(已调信号幅度谱); xlabel(Hz);频谱上应能看到两个主瓣中心大约在 f1、f2 附近。如果只看到一个包络多半是 df 太小或码元数太少谱线没分辨开。3.2 awgn 的信噪比换算与常见错误randn(state, seed(2)); % 固定噪声发生器状态保证可复现 % 在已调信号中加入高斯白噪声 y awgn(y, SNR - 10*log10(0.5) - 10*log10(N), measured, [], dB); figure(3) plot(t, y(1:length(t)), b-); axis([min(t) max(t) -1.5 1.5]); title(加入高斯白噪声后的已调信号); xlabel(Time); ylabel(Amplitude);awgn(x, snr, measured)会先测量输入信号的实际功率再按给定 snr 添加噪声这比默认假设信号功率为 0 dBW 更稳健。三个修正项各自的来历10*log10(0.5)2FSK 每个符号承载 1 bit但平均功率里含正交分量常按 0.5 折算论文里常见这种写法实际取值需与你的功率定义对齐。10*log10(N)把每比特信噪比换算到每采样点因为噪声是按采样点叠加的。SNRpBit/log2(M)每符号信噪比与每比特信噪比的关系M2 时二者相等。注意如果直接写awgn(y, SNR)而不做这些换算你会得到一个明显偏乐观的误码率很多课程报告里误码率比理论值还好的诡异结果就出在这里。噪声是否真的加进去了可以对比 figure(2) 和 figure(3) 的波形figure(3) 的基线应该明显变毛糙。randn(state, seed(2))在新版本 MATLAB 里已不推荐可用rng(seed(2))替代效果一致——固定随机种子是让误码率可复现的关键。4. 相干解调、抽样判决与误码率统计4.1 两路相干解调的结构接收端把 2FSK 拆成上下两路上路用 $\cos(2\pi f_1 t)$ 相乘再低通下路用 $\cos(2\pi f_2 t)$ 相乘再低通。哪一路输出抽样值大就判决为该路对应的符号。判决规则必须与调制规则呼应——调制时 1 对应 f1那么接收端上支路抽样值大就判 1。% 相干解调fsk/eye 同时输出眼图所需数据 z1 ddemod(y, Fc, Fd, Fs, fsk/eye, M, df); figure(4) stem([0:numPlot-1], x(1:numPlot), bx); hold on; stem([0:numPlot-1], z1(1:numPlot), ro); hold off; axis([0 numPlot -0.5 1.5]); title(相干解调后的信号原序列比较); legend(原输入二进制随机序列, 相干解调后的信号); xlabel(Time); ylabel(Amplitude);ddemod是与dmod配对的解调函数fsk/eye表示在解调的同时准备眼图数据。蓝叉是原始码红圈是解调码两者在多数采样点上重合说明链路正确。少数点错开就是误码通常出现在噪声较大的码元处。实际工程里常用非相干解调包络检波或过零检测它对相位不敏感、实现简单代价是抗噪性能比相干解调差约 3 dB。选择相干还是非相干本质是拿同步复杂度换信噪比。4.2 抽样判决与误码率计算% 统计误码率errorSym 为错误符号数ratioSym 为误码率 [errorSym, ratioSym] symerr(x, z1); figure(6) simbasebandex([0:1:5]); title(相干解调后误码率统计);symerr(x, z1)逐符号比较发送序列与接收序列返回错误个数和错误比例。它是整个设计里唯一客观的量化指标前面所有波形图都是定性观察只有 ratioSym 能拿来和理论公式对照。理论误码率相干 2FSK为 $P_e\frac{1}{2}\mathrm{erfc}\left(\sqrt{\frac{E_b}{2N_0}}\right)$。想看曲线是否贴合可以把 SNR 扫一遍snrRange 0:2:12; ber zeros(size(snrRange)); for k 1:length(snrRange) ytmp awgn(dmod(x, Fc, Fd, Fs, fsk, M, df), snrRange(k), measured); ztmp ddemod(ytmp, Fc, Fd, Fs, fsk, M, df); [~, ber(k)] symerr(x, ztmp); end semilogy(snrRange, ber, o-); xlabel(Eb/N0 (dB)); ylabel(BER); grid on;用semilogy因为误码率跨好几个数量级。码元数只有 25 时低信噪比下统计噪声很大——理论误码率 1e-3 意味着要上万码元才稳课程设计里取 25 码元只能看出大致趋势别指望和理论曲线严丝合缝。提示想让误码率统计靠谱把 numSymb 提到几千甚至上万代价是运行变慢而且不再适合 stem 可视化。原理验证和统计验证用两组不同参数更合理。5. 把仿真跑稳的几个进阶技巧5.1 用眼图判断判决时刻是否合适ddemod的fsk/eye输出可以画眼图眼图的张开度直接反映码间干扰和噪声余量。张开最大的位置就是最佳抽样时刻。z1 ddemod(y, Fc, Fd, Fs, fsk/eye, M, df); % e 中包含眼图数据具体字段以所用工具箱版本为准 plot(real(z1(1:min(200, end)))); title(解调输出眼图); grid on;眼线越细、眼睛越张开判决越可靠。如果眼睛几乎闭合先查 Fs 是否够高、df 是否够大再看噪声功率是不是设过头了。5.2 参数联调的对照表调参时最容易顾此失彼下面这张表把常见现象和排查方向对起来现象可能原因处理波形像锯齿、失真严重Fs 不足或未满足奈奎斯特提高 Fs 到 2 倍最高频率以上频谱只有一个主瓣df 太小增大 df 到与 Fd 同量级误码率异常低SNR 换算漏项检查 log10(N)、log10(0.5) 修正误码率总在 0.5 附近判决规则与调制反了交换上下支路判决门限结果每次不同随机种子未固定用 rng(seed) 固定状态5.3 与 Simulink 建模的取舍设计正文同时提到 Simulink 环境它和脚本代码各有适用面。Simulink 适合动态观察信号在各级之间的流动把 Bernoulli 随机源、2FSK 调制、AWGN 信道、相干解调、误码率计算器拖成框图运行时模块自动更新调整参数不必改一行代码适合快速验证系统结构。脚本代码的优势在于批量扫参数——上面把 SNR 从 0 扫到 12 dB 那段循环Simulink 里做等价操作要配置参数扫描或写回调反而啰嗦。我一般的做法是先用 Simulink 搭一遍结构确认每级波形都对再用脚本复刻并做统计扫描。两者参数定义一致时结果可以互相印证。需要注意 Simulink 里 AWGN Channel 模块的信噪比定义是 Eb/N0 还是 SNR模式不同结论差很多倍这个和脚本里手写换算是一个道理——凡是涉及信噪比先把定义对齐再比较数字。最后一步通常是把误码率随信噪比变化的曲线和理论值画在同一条 semilogy 图上两条线平行且间距在小信噪比区收窄就说明仿真链路和理论模型是一致的如果斜率对不上问题多半在噪声功率换算或判决门限回到 3.2 和 4.2 的换算项逐条核对即可。本文还有配套的精品资源点击获取