简介:这份面向通信原理课程设计学习者的2FSK调制解调系统设计文档,聚焦MATLAB7.0环境下的数字通信链路仿真与课程设计报告撰写。内容围绕二进制随机信源、开关法2FSK调制、加性高斯白噪声信道、相干解调及抽样判决展开,涵盖发送滤波、接收滤波与信宿等模块,并给出源程序与仿真波形,可用于观察调制信号、信道叠加噪声后的波形及解调眼图,绘制信噪比与误码率曲线,完成系统性能评价。压缩包仅含1个doc文件,约579KB,适合直接查阅课程设计结构、参数设置与仿真思路。已有855人学习,可作为通信原理课程设计、MATLAB仿真入门和2FSK调制解调实验的参考,帮助读者理解开关法调制与相干解调的模块划分、关键参数及性能分析方法。
1. 为什么课程设计里 2FSK 总翻车:这套 MATLAB 仿真能交付什么
2FSK 调制与解调系统设计与仿真这个题目,在通信原理课程设计里出镜率极高,但真正一次跑通的人不多——大部分时间不是卡在理论上,而是卡在 MATLAB 的参数对不上:载频、采样率、频偏、信噪比折算,四个数随便错一个,波形和误码率曲线就全歪。这套基于 MATLAB 7.0 的完整链路,覆盖信源产生、2FSK 调制、加性高斯白噪声信道、带通滤波、相干与非相干两路解调、抽样判决、眼图观测和误码率统计,解决的问题很具体:把书本上那两张原理图,变成能出波形、能出眼图、能出 SNR-BER 曲线的可执行脚本。
它适合两类人:正在做通信原理课设、需要交一份「有波形有数据有对比」的报告;以及已经会调 dmod/ddemod、但画出来的误码率曲线明显不符合理论趋势,想回头找原因的人。下面按建模、搭链路、统计、排坑、进阶的顺序拆开讲,每个参数为什么这么取都会说清楚。
2. 开关法建模:两个载频、三个采样率参数怎么互相卡死
2.1 开关法与调频法的相位差异会咬到哪一步
2FSK 信号的产生有两条路。调频法用一个压控振荡器,载波频率随基带信号在 f1 和 f2 之间连续变化,相邻码元交界处相位连续,本质上是 CPFSK;开关法用两个独立的振荡器分别产生 f1 和 f2,由基带矩形脉冲控制开关选择输出,两个码元交界处相位一般不连续,跳变多少取决于两路振荡器当时的瞬时相位。
这套设计选开关法,不是因为它更好,而是因为它和代码对得上。MATLAB 通信工具箱里的dmod(...,'fsk',M,df)内部就是把符号映射成两个频率分量再拼接,属于典型的频率切换,你拿它跑出来的就是开关法的波形。任务书里要求「键控法产生 2FSK」,两者正好一致,报告里写「采用开关法,相邻码元相位不一定连续」才算自洽。反过来说,如果任务书写的是「相位连续」,就不能直接拿dmod的'fsk'交差,得自己按每个码元累加相位 2πfT 重写调制,否则答辩时被追问「你的连续相位体现在哪一段代码」会答不上来。
相位不连续带来的实际后果,落在相干解调的低通输出上。本地恢复的 cos(2πf1t) 与接收信号相乘后,低通输出是一个受相位差影响的量,码元边界的相位跳变会让这个量出现一段瞬态。只要抽样判决时刻落在码元中点、也就是眼图张开最大的位置,瞬态还没蔓延到判决点,误码率就不会因此崩掉。但如果你把抽样时刻设偏,或者用自己手写的积分清零式判决器而没做定时对齐,就会看到眼图迹线糊成一片、误码率莫名飙高——这条在后面排查章节里还会出现。
另外,选开关法有个隐藏好处:它让「2FSK 可以看作两路不同载频的 ASK 叠加」这个结论变得直观。相干解调的两条支路,本质上就是两个中心频率不同的 ASK 接收机,各自乘本振、低通、抽样,最后比大小。理解到这个层面,后面调带通滤波器的中心频率和带宽时,就不用死记参数了。
2.2 采样率、载频、码速率:三个数定死之前先算约束
这套代码里最容易被忽略、又最容易出事的一组参数是Fc=10、Fs=40、Fd=1。三个数看着随便填,其实互相卡得很紧:
| 参数 | 取值 | 物理含义 | 隐含约束 |
|---|---|---|---|
| Fc | 10 Hz | 标称载频 | Fc ± df/2 必须低于 Fs/2 |
| Fs | 40 Hz | 系统采样率 | Fs/Fc 建议不低于 8 |
| Fd | 1 Hz | 码速率 Rb | 决定射频带宽下限 |
| N = Fs/Fd | 40 | 每码元采样点数 | 影响 awgn 折算与眼图迹线数 |
| df | 10 Hz | 两载频间隔 | 决定正交性与占用带宽 |
| M | 2 | 进制数 | 固定为二进制 |
先看 Fs/Fc = 4,也就是一个载波周期只有 4 个采样点。这是能画出「看起来像正弦」的绝对下限,plot出来已经接近折线;想让你报告里的调制波形经得起看,最好把 Fs/Fc 提到 8 以上。很多人的波形图被质疑「这不是正弦」,根子就在这里,改 Fs 或者降 Fc 都能解决,但降 Fc 会连带压缩可用带宽,通常还是提 Fs 更省事。
再看 Fc/Fd = 10,也就是一个码元内包含 10 个完整的载波周期。这个比值决定了「频率」这个概念在单个码元内是否成立:如果每码元只有一两个载波周期,频率切换在时域上就退化成相位突变,频谱完全糊掉,带通滤波器也没法把 f1 和 f2 分开。工程上一般要求每码元至少 5 个载波周期,10 是个舒服的取值。
最后是 Fs/Fd = N = 40,每码元 40 个采样点。这个数不只是画图好看,它还直接进入后面awgn的信噪比折算公式,改了这个值而忘了改折算项,整条误码率曲线就会整体平移。
2.3 频偏 df 的取值:正交间隔与混叠边界
dmod的'fsk'模式里,df是两个载频之间的间隔,实际使用的两个频率是Fc - df/2和Fc + df/2。代进这套参数,f1 = 5 Hz、f2 = 15 Hz。而奈奎斯特频率是 Fs/2 = 20 Hz,f2 距离边界只剩 5 Hz 余量,2FSK 的射频带宽粗估为 |f2-f1| + 2Rb = 12 Hz,上边沿顶到 16 Hz 附近,勉强没越界。这就是为什么 df 不能随手填大:填到 16,f2 就变成 18 Hz,双边带直接折返混叠,误码率曲线会在某个 SNR 之后压平不降,看着特别像「仿真坏了」。
另一个约束是正交性。相干解调要求两个频率的间隔是 1/(2Tb) 的整数倍,非相干解调要求是 1/Tb 的整数倍。Tb = 1/Fd = 1 s,所以相干要求 df 是 0.5 的整数倍、非相干要求 df 是 1 的整数倍。df = 10 同时满足两者,这也是这套参数能让相干和非相干两条支路共用同一组载频设置、直接对比的前提。如果 df 取 8 或 9,非相干支路的正交性就破了,你会发现非相干解调的误码率反而比相干还低,那不是算法厉害,是参数没配对。
下面这段自检脚本建议放在主程序最前面跑一遍,比事后看波形猜原因省事得多:
% 2FSK 参数自检:混叠、每码元周期数、正交间隔 Fc = 10; Fs = 40; Fd = 1; df = 10; f1 = Fc - df/2; f2 = Fc + df/2; fprintf('f1=%.2f Hz, f2=%.2f Hz, Nyquist=%.2f Hz\n', f1, f2, Fs/2); assert(f2 < Fs/2, 'f2 越过奈奎斯特频率,必然混叠,请增大 Fs 或减小 df'); fprintf('每码元载波周期数 Fc/Fd = %.1f\n', Fc/Fd); fprintf('每载波周期采样点数 Fs/Fc = %.1f\n', Fs/Fc); B = abs(f2-f1) + 2*Fd; % 2FSK 射频带宽粗估(双边) fprintf('射频带宽约 %.2f Hz,上边沿约 %.2f Hz\n', B, f2 + Fd); Tb = 1/Fd; fprintf('df/(1/(2Tb)) = %.2f 相干解调应接近整数\n', df/(1/(2*Tb))); fprintf('df/(1/Tb) = %.2f 非相干解调应接近整数\n', df/(1/Tb));这段脚本干的事就是把你脑子里的三个约束变成可执行的断言。assert那一行是后悔药:混叠一旦发生,后面所有波形和曲线都白跑,早点报错比事后对着一条压平的 BER 曲线发呆强。输出里的两个比值如果明显偏离整数,就说明正交性破了,要么改 df,要么换解调方式。参数说明方面,Fc/Fd控制在 5 到 20 之间、Fs/Fc不低于 8、f2 + Fd < Fs/2,这三条守住,链路基本不会出结构性错误。
3. 从 dmod 到 ddemod:把调制解调链路串起来的五段脚本
3.1 信源与基带波形:randsrc 与单极性矩形波
信源部分要交两样东西:二进制随机序列本身,和它对应的单极性矩形基带波形。原始代码里只画了stem杆图,那是符号级的序列,不是基带波形,报告里如果只有杆图,「数字基带信号采用单极性矩形波」这条要求其实没满足。补上rectpulse做零阶保持,一个码元重复 N 个采样点,才是真正的矩形波:
M = 2; % 二进制调制 numSymb = 25; % 用于波形展示的码元数 Fs = 40; Fd = 1; Fc = 10; df = 10; N = Fs/Fd; % 每码元采样点数 = 40 x = randsrc(numSymb,1,[0:M-1]); % 0/1 等概随机序列 baseband = rectpulse(x, N); % 零阶保持,得到单极性矩形波 t_bb = (0:length(baseband)-1)/Fs; figure(1); subplot(2,1,1); stem(0:numSymb-1, x, 'bx'); axis([0 numSymb-1 -0.2 1.2]); title('二进制随机序列'); xlabel('Symbol Index'); ylabel('Amplitude'); subplot(2,1,2); plot(t_bb, baseband, 'LineWidth', 1.2); axis([0 10 -0.2 1.2]); title('单极性矩形基带信号(前 10 码元)'); xlabel('Time (s)'); ylabel('Amplitude');randsrc的第三个参数[0:M-1]表示从 0 到 M-1 等概取值,这里就是 0 和 1。rectpulse是通信工具箱里的零阶保持函数,第二个参数是每个符号的重复次数,必须等于Fs/Fd,否则时间轴和采样率对不上,波形图横坐标就是假的。numSymb = 25只适合截图,不适合做误码率统计,这一点在下一章会展开。如果你手上没有通信工具箱,baseband = reshape(repmat(x',N,1),[],1)能达到同样效果,只是可读性差一点。
3.2 调制与信道:dmod 的频偏参数与 awgn 的电平折算
调制这一步就是一行dmod,没什么花活,但它的输出长度、时间轴构造方式、以及后面加噪的功率折算,是三个容易出错的地方:
% 2FSK 调制:键控法,f1 = Fc-df/2,f2 = Fc+df/2 y = dmod(x, Fc, Fd, Fs, 'fsk', M, df); numPlot = 15; % 只画前 15 个码元,避免横轴过密 numModPlot = numPlot * Fs; % 对应采样点数 t = (0:numModPlot-1)/Fs; % 仿真时间轴 figure(2); plot(t, y(1:numModPlot), 'b-'); axis([0 max(t) -1.5 1.5]); title('2FSK 调制后的信号'); xlabel('Time (s)'); ylabel('Amplitude'); % 加入加性高斯白噪声 SNRpBit = 8; % 每比特信噪比 Eb/N0 (dB) SNR = SNRpBit / log2(M); % 折算成每符号信噪比(M=2 时相同) seed = [12345 54321]; randn('state', seed(2)); % 固定噪声种子,保证可复现 y_noisy = awgn(y, SNR - 10*log10(0.5) - 10*log10(N), 'measured', [], 'dB'); figure(3); plot(t, y_noisy(1:numModPlot), 'b-'); axis([0 max(t) -1.5 1.5]); title('加入高斯白噪声后的已调信号'); xlabel('Time (s)'); ylabel('Amplitude');dmod的调用形式是dmod(x, Fc, Fd, Fs, 'fsk', M, df),七个参数依次是符号序列、标称载频、码速率、采样率、调制方式、进制数、频率间隔。第七个参数df是最容易漏的,漏了会报参数个数错误;填错则直接影响上一节算好的正交性。
真正需要解释的是awgn那一行里的两个修正项。SNRpBit是每比特信噪比,单位 dB;10*log10(0.5)对应 2FSK 把功率分摊到两个频率分量上,单个支路的功率只有总功率的一半;10*log10(N)是把每符号信噪比折算到每个采样点上,因为awgn是按采样点加噪的。两个修正项合起来,才是「给定 Eb/N0,实际该往每个采样点上加多少噪声」。这两个项在 MATLAB 官方示例里是成套出现的,但一旦你改了Fs、Fd或者调制方式,就必须跟着重算,照抄别人的数字是曲线整体平移的头号原因。
randn('state', ...)这行在旧版本里用于固定噪声随机种子,新版 MATLAB 已改为rng(seed)。固定种子的意义在于:调参数的时候误码率不会因为随机噪声本身波动而在 1e-2 和 1e-3 之间乱跳,你能确定变化是参数引起的。
3.3 相干与非相干解调:ddemod 的两种调用与眼图
解调部分保留两条支路,用同一组含噪信号,这样报告里的对比才成立:
% 相干解调:本地载波与接收信号相乘 -> 低通 -> 抽样判决 figure(4); z1 = ddemod(y_noisy, Fc, Fd, Fs, 'fsk/eye', M, df); title('相干解调后的眼图'); % 非相干解调:带通 -> 包络检波 -> 抽样判决 figure(6); z2 = ddemod(y_noisy, Fc, Fd, Fs, 'fsk/eye/noncoh', M, df); title('非相干解调后的眼图'); % 原序列与两路解调结果的逐位对比 figure(5); stem(0:numPlot-1, x(1:numPlot), 'bx'); hold on; stem(0:numPlot-1, z1(1:numPlot), 'ro'); hold off; axis([0 numPlot-1 -0.5 1.5]); legend('原输入序列','相干解调输出'); title('相干解调结果与原序列对比'); figure(7); stem(0:numPlot-1, x(1:numPlot), 'bx'); hold on; stem(0:numPlot-1, z2(1:numPlot), 'ro'); hold off; axis([0 numPlot-1 -0.5 1.5]); legend('原输入序列','非相干解调输出'); title('非相干解调结果与原序列对比');ddemod的第一个参数是接收信号,后面依次是载频、码速率、采样率、解调方式字符串、进制数、频率间隔。字符串'fsk/eye'表示相干解调并额外画出眼图,'fsk/eye/noncoh'表示非相干解调加眼图;/eye这个后缀只是让函数顺手画一张眼图,不改变解调算法本身。眼图的作用是给你一个定时质量的直观判据:迹线张开得越宽,抽样余量越大;如果迹线糊成一条带,说明定时或滤波出了问题,这时候再看误码率就没意义了。
两个细节值得注意。一是ddemod的输出长度和输入符号数一致,但内部有滤波器延迟,前几个符号可能因为瞬态被判错,统计误码率时如果发现错误集中在开头几个位置,那是滤波器群时延导致的,不是算法错。二是相干解调需要接收端知道确切的载波相位,仿真里ddemod默认本地载波与发射端严格同相,这是理想假设;真实系统里要靠载波恢复电路,会引入相位误差,这个差别在报告里最好点一句,显得你知道边界在哪。
4. 误码率曲线:25 个码元统计不出 1e-3,要扫多少才算数
4.1 单点 symerr 的分辨率问题
原始代码里numSymb = 25,然后[errorSym, ratioSym] = symerr(x, z1)。这个写法本身没错,但 25 个码元能给出的误码率分辨率是 1/25 = 4e-2,也就是最低只能测到 4% 的误码率。如果你在 8 dB 信噪比下测到 0 个错误,那不代表误码率是 0,只代表错误率低于 4%。报告里把这个数写成「误码率约为 0」是可以的,写成「误码率 1e-4」就是编的。
要统计到 1e-3 这个量级,至少需要 1e5 个码元,才能期望出现 100 个错误,统计置信度才够看。代价是仿真时间:1e5 个码元、每码元 40 个采样点,就是 4e6 个采样点,dmod和ddemod各跑一遍,普通笔记本几秒到几十秒能出结果,完全可以接受。所以合理的做法是分工:波形图用 15 到 25 个码元,图清爽;误码率统计单独开一轮,用 1e5 个码元,不画波形。
4.2 SNR 扫描:把曲线跑出来
单点误码率说服力有限,报告里真正撑场面的是 SNR-BER 曲线。做法是把信噪比做成向量,循环调制、加噪、解调、统计,两路解调各存一条曲线:
EbN0_dB = 0:2:12; % 每比特信噪比扫描范围 numSymb = 1e5; % 统计用码元数,保证低误码率可分辩 ber_coh = zeros(size(EbN0_dB)); ber_non = zeros(size(EbN0_dB)); for k = 1:numel(EbN0_dB) x = randsrc(numSymb,1,[0 1]); y = dmod(x, Fc, Fd, Fs, 'fsk', 2, df); % Eb/N0 -> 每采样点 SNR:双频功率减半 + 过采样增益 snr_samp = EbN0_dB(k) - 10*log10(0.5) - 10*log10(N); y = awgn(y, snr_samp, 'measured', [], 'dB'); z1 = ddemod(y, Fc, Fd, Fs, 'fsk', 2, df); % 相干 z2 = ddemod(y, Fc, Fd, Fs, 'fsk/noncoh', 2, df); % 非相干 [~, ber_coh(k)] = symerr(x, z1); [~, ber_non(k)] = symerr(x, z2); fprintf('Eb/N0=%2d dB BER_coh=%.3e BER_non=%.3e\n', ... EbN0_dB(k), ber_coh(k), ber_non(k)); end figure(8); semilogy(EbN0_dB, ber_coh, 'bo-', EbN0_dB, ber_non, 'rs-', 'LineWidth', 1.2); grid on; xlabel('E_b/N_0 (dB)'); ylabel('BER'); legend('相干解调','非相干解调','Location','southwest'); title('2FSK 误码率随信噪比变化曲线');循环体里只有一处需要你根据自己参数改的,就是snr_samp那一行。-10*log10(0.5)对应双频分路、-10*log10(N)对应过采样,这两个修正项和 3.2 节完全一致,改参数时两边要同步改,否则单点图和曲线图会互相矛盾。semilogy是对数纵轴,误码率跨几个数量级时必须用它,线性轴上看不出低信噪比段的差异。
运行时会看到低信噪比段两路误码率都接近 0.5,那是正常的,信噪比太低时判决基本等于掷硬币。真正有信息量的是曲线开始下弯的那一段,以及两条曲线之间的间距。
4.3 叠上理论曲线:判断仿真对不对的唯一标准
仿真曲线画出来只是一半,能不能站住要看它和理论值贴不贴。2FSK 的两条理论公式可以直接用qfunc算:
EbN0 = 10.^(EbN0_dB/10); % dB 转线性 ber_th_coh = qfunc(sqrt(EbN0)); % 相干 2FSK:Q(sqrt(Eb/N0)) ber_th_non = 0.5 * exp(-EbN0/2); % 非相干 2FSK:0.5*exp(-Eb/(2N0)) figure(9); semilogy(EbN0_dB, ber_coh, 'bo', EbN0_dB, ber_th_coh, 'b-', ... EbN0_dB, ber_non, 'rs', EbN0_dB, ber_th_non, 'r-'); grid on; xlabel('E_b/N_0 (dB)'); ylabel('BER'); legend('相干-仿真','相干-理论','非相干-仿真','非相干-理论','Location','southwest');相干 2FSK 的理论误码率是 Q(sqrt(Eb/N0)),非相干是 0.5·exp(-Eb/(2N0))。这两条式子在大信噪比下大约差 1 dB 量级的信噪比,也就是说同样要达到 1e-4 的误码率,非相干解调要多花约 1 dB。如果你跑出来的两条仿真曲线间距远大于这个数,或者仿真点系统性地偏离理论线几个 dB,那基本可以判定是信噪比折算写错了,而不是「我的系统性能特别好」。
另一个判据是曲线的斜率。理论和仿真在对数坐标下应该近似平行,如果仿真曲线在高信噪比段突然变平,那是碰到了分辨率下限(码元数不够),或者出现了混叠。把numSymb提到 1e6 再看,如果曲线继续往下走,就是分辨率问题;如果不走,回头查 2.3 节的assert。
5. 踩坑排查:五条从波形到误码率的翻车记录
5.1 波形与滤波器环节的两次翻车
坑一:调制波形画出来像三角波,被质疑「这不是正弦」。现象是figure(2)里的已调信号边缘笔直、峰值尖锐,完全看不出正弦的形状。原因只有一个:每个载波周期的采样点太少。原始参数 Fs/Fc = 4,一个周期四个点,plot用直线把点连起来,出来的当然是折线。解决办法是把Fs提到 160 或把Fc降到 5,保证 Fs/Fc 不低于 8;后者会连带压缩可用带宽,通常选前者。改完记得同步改N = Fs/Fd和awgn里的10*log10(N),这两处是联动的,只改一处会让波形好看但误码率错。
坑二:Simulink 里带通滤波器一加,解调波形严重失真。现象是滤波后的信号幅度忽大忽小、包络畸变,判决输出成片出错。常见原因有三个:带通中心频率没对准 f1 和 f2;带宽取得比码速率还窄,把有用边带削掉了;滤波器阶数给得太高,群时延陡变导致码元间干扰。解决思路是先按 f1、f2 分别设两个带通,中心频率精确对齐,带宽取 2 倍码速率左右,阶数控制在 4 到 6 之间,然后在滤波器输出端接一个示波器看波形有没有明显拖尾。如果拖尾严重,说明群时延没补偿,可以在判决前加一段延时对齐,或者在报告里明确说明这是滤波器引入的固定延迟。这一条是血泪经验:滤波器参数不是越陡越好,阶数上去了,时域拖尾会让你怀疑人生。
5.2 信噪比与判决环节的三次翻车
坑三:误码率曲线在高信噪比段压平,怎么加码元都不降。现象是曲线降到 1e-2 附近就横住了,和理论线明显分叉。原因大概率是混叠:df取大了,f2 = Fc + df/2 逼近甚至越过 Fs/2,两个频率分量的边带折返回来互相污染,这时候再怎么提信噪比都没用,因为干扰不是噪声而是自己的镜像。解决办法是跑 2.3 节那段自检脚本,确认 f2 + Fd 小于 Fs/2;不满足就提高 Fs 或者减小 df,同时回头检查 df 是否还满足正交间隔的整数倍要求。这个坑的迷惑性在于波形图看着挺正常,只有误码率曲线会露馅。
坑四:仿真曲线整体比理论线偏移好几 dB,但形状完全对。现象是两条曲线平行,只是横向平移,说明算法没问题、功率标定错了。原因基本锁定在awgn的修正项上:换了Fs、Fd、M或者调制方式之后,-10*log10(0.5)和-10*log10(N)没有跟着重算,或者从别处抄来的示例里这两个系数根本对应不同的调制体制。解决办法是把折算公式重新推一遍,或者干脆用awgn(y, SNR, 'measured')让函数自己测功率,先确认量级对不对,再回头用解析折算做精调。判断是否属于这个坑有个简单办法:看偏移量是不是恰好等于某个 10*log10 的整数倍,是的话几乎可以确定。
坑五:Simulink 的误码率计算模块一直报错,调不出来。现象是 Error Rate Calculation 模块提示维度不匹配或采样率不一致,换了几种接法都不行。原因通常是收发两路的信号采样率不同(一路是符号率、一路是采样率),或者模块的延迟参数没设、把收发序列错位对齐了。这个问题在图形化环境里排查成本很高,因为它不告诉你哪一位错了。比较务实的做法是放弃在 Simulink 里算误码率,用 To Workspace 模块把发送序列和判决输出导出到工作区,在脚本里用symerr算,几行代码的事,还能顺便画曲线。我自己遇到这类模块报错,一般不在图形界面里死磕,直接退回脚本层,可控性高得多。
6. 进阶:升余弦滤波与眼图,让报告里的曲线站得住
链路跑通、曲线出来之后,还有一步能把报告的质量拉开档次:在接收端加一级升余弦滤波器,把带外噪声滤掉,同时用眼图证明你的定时是干净的。
Delay = 3; R = 0.5; % 群时延 3 个码元,滚降系数 0.5 [yf, tf] = rcosine(Fd, Fs, 'fir', R, Delay); % 设计升余弦 FIR [yo2, to2] = rcosflt(y_noisy, Fd, Fs, 'filter', yf); % 对含噪信号滤波 figure(10); plot(t, y_noisy(1:numModPlot), 'r-'); hold on; plot(to2, yo2, 'b-'); hold off; axis([0 30 -1.5 1.5]); legend('含噪已调信号','升余弦滤波后'); title('升余弦滤波前后波形比较'); xlabel('Time (s)'); ylabel('Amplitude'); eyediagram(yo2(1:200*N), N); % 每屏 200 码元,每 trace N 点 title('升余弦滤波后的眼图');rcosine的第四个参数是滚降系数 R,取 0.5 是个折中:R 越小频谱越陡、频带利用率越高,但时域拖尾越长,对定时误差越敏感;R 接近 1 时拖尾短、鲁棒,但占用带宽翻倍。做课设报告,0.5 足够交差,真要论证可以扫 0.2、0.5、0.8 三组做对比。第五个参数 Delay 是滤波器的群时延,单位是码元数,取 3 意味着输出会比输入滞后 3 个码元;所以to2和t对不齐是正常的,画图时不要硬把两条曲线起点拉平,那等于人为制造了一个相位错误。
eyediagram的第二个参数必须等于Fs/Fd,也就是每码元采样点数。这个数填错是眼图糊掉的常见原因:填大了,一个 trace 里塞进好几个码元,迹线互相重叠;填小了,只显示码元的一部分,看不出张开程度。第一段参数200*N控制参与叠加的采样点总数,200 个码元叠出来的眼图清晰度和计算量比较平衡。判读眼图就看两点:眼睛张开的高度(噪声容限)和张开的位置(最佳抽样时刻),两者都正常,你报告里的误码率数据才有支撑。
从那以后我每次做这类仿真,都强制自己先跑一遍参数自检、再跑单点波形、最后才跑扫描曲线,顺序反了就会在一条压平的曲线上浪费一整晚。希望帮到你。
本文还有配套的精品资源,点击获取