资讯动态

数字通信原理实验:信号频谱分析从入门到工程实践

发布时间:2026/10/14 9:53:40 来源:尧图企业网站定制
1. 信号频谱分析实验到底在做什么数字通信原理这门课很多人第一次真正感到“虚”就是从信号频谱分析实验开始的。课本上傅里叶变换的公式推导还能勉强跟上一到实验室打开软件看见满屏的频谱图立刻就不知道自己在看什么了。我当年也是这样盯着示波器上那根不断跳动的谱线心里想的全是“这玩意儿到底有什么用”。其实这个实验的核心目标非常朴素让你亲眼看到“时域看不见的东西频域里一目了然”。一个方波在示波器上就是高低电平的切换但在频谱仪上你会看到基波加上一系列奇次谐波幅度按1/n衰减。这个直观感受一旦建立起来后面学采样定理、学滤波器设计、学调制解调你脑子里都会自动浮现出频谱的画面而不是死记公式。这个实验通常面向通信工程、电子信息工程专业的本科生一般安排在大三上学期。前置知识需要掌握傅里叶级数、傅里叶变换的基本概念以及MATLAB或Python的基本操作。实验本身不复杂但它是整个数字通信课程体系的地基——后面所有的调制识别、信道均衡、频谱感知全都建立在“你能看懂频谱”这个前提之上。我见过太多同学做完这个实验就扔到一边等到期末复习调制解调的时候又回来翻实验报告结果发现当时根本没理解。所以这篇文章我会把整个实验从设计思路到实操细节全部拆开讲清楚包括那些实验指导书上不会写、但实际操作中一定会踩的坑。2. 实验整体设计与方案选型2.1 为什么选择MATLAB而不是硬件频谱仪大部分高校的信号频谱分析实验有两种实现路径一种是使用硬件频谱分析仪另一种是用MATLAB或Python做软件仿真。我两种都做过说实话各有优劣但作为教学实验软件方案的优势更明显。硬件频谱仪的好处是“真实”你能摸到旋钮、看到真实的信号输入输出对仪器的操作也会更熟悉。但问题在于硬件频谱仪的价格通常在几万到几十万实验室能分给每个学生的机时非常有限而且硬件频谱仪的参数调节不够灵活你想改一个采样率可能要翻好几层菜单远不如在代码里改一个变量来得快。MATLAB方案的核心优势在于参数完全可控、结果可复现、中间过程可观察。你可以把FFT的点数从1024改到4096立刻看到频率分辨率的变化你可以把窗函数从矩形窗换成汉宁窗马上观察到频谱泄漏的改善。这种“改一个参数、看一个效果”的交互式学习体验是硬件设备很难提供的。注意如果你所在的实验室同时提供硬件和软件两种方案我的建议是先用MATLAB把原理吃透再去硬件频谱仪上验证。反过来做的话你很容易被硬件操作的各种细节分散注意力反而忽略了频谱本身的意义。2.2 实验信号的选择逻辑实验指导书通常会要求你分析几种典型信号正弦波、方波、三角波、矩形脉冲、以及带噪声的信号。这个选择不是随便定的每种信号对应一个核心知识点。正弦波是最基础的它的频谱只有一根谱线用来验证FFT的基本正确性。如果你连正弦波的频谱都分析不对后面的就不用做了。方波用来展示谐波的概念——理论上方波包含无穷多次奇次谐波但在实际频谱图上你只能看到有限根谱线这个“有限”和“无穷”之间的差异正好引出了带宽和滤波的概念。三角波的谐波衰减速度比方波快幅度按1/n²衰减对比两者的频谱可以直观理解不同波形的频谱特性差异。矩形脉冲信号则引出了频谱泄漏和频率分辨率这两个关键概念。当脉冲宽度不是采样周期的整数倍时频谱会出现泄漏原本应该集中的能量会扩散到邻近的频率点上。这个问题在实际通信系统中非常关键因为泄漏会导致相邻信道的干扰。带噪声的信号用来模拟真实通信环境。你会看到噪声的频谱是均匀分布的白噪声而信号的谱线会从噪声基底中“冒”出来。信噪比越低谱线越难辨认这就引出了后续检测和估计的问题。2.3 采样率和FFT点数的确定方法这是实验中最容易出错的地方也是最能体现“你是否真的理解”的环节。采样率的选取必须满足奈奎斯特采样定理采样率fs必须大于信号最高频率分量的两倍。但实际操作中我建议至少取2.5倍到4倍留出足够的余量。举个例子你要分析一个基频为1kHz的方波理论上方波的最高次谐波是无穷大但实际上你只需要关心前几次谐波。假设你关心到第10次谐波也就是10kHz那么采样率至少要是20kHz。但为了频谱图好看、避免混叠我通常会取40kHz甚至更高。FFT点数的选择直接决定了频率分辨率。频率分辨率Δf fs / N其中N是FFT点数。如果你取fs 40kHzN 1024那么Δf ≈ 39Hz。这意味着频率轴上相邻两个点的间隔是39Hz如果两个信号的频率差小于39Hz你在频谱图上就分不清它们。但N也不是越大越好。N越大计算量越大而且如果信号本身的持续时间不够长补零到很大的N只会让频谱看起来更“平滑”并不会真正提高分辨率。真正的频率分辨率取决于信号的观测时间T N / fs而不是N本身。参数选取原则常见取值注意事项采样率fs≥ 2.5倍最高关心频率40kHz基频1kHz方波留余量防混叠FFT点数N2的整数次幂1024、2048、4096兼顾分辨率与计算量频率分辨率Δffs / N约39Hzfs40k, N1024由观测时间决定窗函数根据信号类型选择矩形窗/汉宁窗/汉明窗矩形窗适合整周期采样3. 核心细节解析与实操要点3.1 时域采样与频域分析的对应关系很多同学做实验时把时域和频域当成两个独立的东西这是最大的认知误区。时域采样和频域分析之间有一条铁律时域的离散化对应频域的周期化时域的周期化对应频域的离散化。具体来说当你对连续信号进行采样时频域中信号的频谱会以采样频率为周期进行延拓。如果原信号的最高频率超过了fs/2延拓后的频谱就会发生混叠高频成分会“折叠”到低频区域导致你看到的频谱是错的。这个原理在实验中怎么体现你可以故意把采样率设得很低比如对一个1kHz的方波只取1.5kHz的采样率然后观察频谱图。你会看到原本应该在3kHz、5kHz的谐波消失了取而代之的是一些莫名其妙的低频成分。这就是混叠的直观表现。反过来当你对信号做FFT时实际上隐含了一个假设你截取的这段信号是周期性的周期就是观测时间T。如果信号的实际周期和T不匹配频谱就会泄漏。这就是为什么实验指导书通常要求你“取整数个周期”进行分析。3.2 窗函数的选取与频谱泄漏的抑制窗函数是频谱分析中最容易被忽视、但实际影响最大的环节。矩形窗也就是不加窗的频率分辨率最高但旁瓣衰减最慢泄漏最严重。汉宁窗的旁瓣衰减快但主瓣变宽频率分辨率下降。我个人的经验是如果你能保证整周期采样就用矩形窗如果不能就用汉宁窗或汉明窗。整周期采样在实际通信系统中几乎不可能做到因为信号的频率和相位都是未知的所以工程上汉宁窗用得最多。实验中的典型操作是先对同一个信号分别加矩形窗和汉宁窗做FFT然后把两张频谱图叠在一起对比。你会看到矩形窗的谱线更“尖”但底部有很多小鼓包汉宁窗的谱线更“胖”但底部干净得多。这个对比会让你对窗函数的 trade-off 有非常直观的理解。提示如果你用的是Python的scipy库scipy.signal.get_window可以方便地生成各种窗函数。MATLAB里直接用hanning(N)或hamming(N)即可。注意窗函数的长度必须和信号长度一致否则会出错。3.3 频谱幅度的归一化处理FFT的输出是一个复数数组直接取模得到的是幅度谱但这个幅度值并不是信号的真实幅度。原因在于FFT本身是一个求和运算N点FFT的结果会比真实幅度大N倍对于单频信号。正确的归一化方法是对于单频信号幅度谱除以N/2对于直流分量除以N。如果你加了窗函数还需要除以窗函数的相干增益coherent gain也就是窗函数所有系数的平均值。这个细节很多实验指导书都不写但不做归一化的话你看到的幅度值会大得离谱根本没法和其他测量结果对比。我第一次做实验的时候就吃了这个亏频谱图上正弦波的幅度显示为512我还以为是信号发生器坏了后来才发现是没归一化。3.4 频率轴的正确构建FFT输出的频率轴不是从0到fs而是从0到fs/2正频率部分然后从-fs/2到0负频率部分。对于实信号频谱是对称的所以你只需要看前一半。构建频率轴的代码通常是这样的import numpy as np fs 40000 # 采样率 N 1024 # FFT点数 f np.fft.fftfreq(N, 1/fs) # 包含正负频率 f_positive f[:N//2] # 只取正频率部分或者用np.fft.rfftfreq(N, 1/fs)直接得到正频率轴。MATLAB里对应的命令是f (0:N/2-1) * fs / N。这个步骤看起来简单但如果你搞错了频率轴整个频谱图的解读就全错了。我见过有同学把频率轴画成了0到fs结果把镜像频率也画进去了频谱图看起来像是信号被“压缩”了一半。4. 完整实操流程与关键环节实现4.1 实验环境搭建与基础代码框架先确认你的工具链。MATLAB需要安装Signal Processing ToolboxPython需要numpy、scipy、matplotlib三个库。如果你用Python建议用Jupyter Notebook因为可以交互式地改参数、看结果比脚本文件方便得多。基础代码框架我习惯分成四个模块信号生成、采样、FFT分析、绘图。这样结构清晰改哪个部分都不会影响其他部分。import numpy as np import matplotlib.pyplot as plt from scipy import signal # 参数设置 fs 40000 # 采样率 T 0.1 # 信号持续时间 N int(fs * T) # 总采样点数 t np.arange(N) / fs # 时间轴 # 信号生成 f0 1000 # 基频 x signal.square(2 * np.pi * f0 * t) # 方波信号 # FFT分析 N_fft 1024 X np.fft.rfft(x[:N_fft] * np.hanning(N_fft)) freq np.fft.rfftfreq(N_fft, 1/fs) magnitude np.abs(X) / (N_fft / 2) # 归一化 # 绘图 plt.figure(figsize(12, 6)) plt.subplot(2, 1, 1) plt.plot(t[:1000], x[:1000]) plt.xlabel(时间 (s)) plt.ylabel(幅度) plt.title(时域波形) plt.subplot(2, 1, 2) plt.plot(freq, magnitude) plt.xlabel(频率 (Hz)) plt.ylabel(幅度) plt.title(频谱) plt.xlim(0, 10000) plt.tight_layout() plt.show()这段代码可以直接跑你会看到一个方波的时域波形和它的频谱。频谱上应该在1kHz、3kHz、5kHz、7kHz、9kHz处看到谱线幅度依次递减。4.2 方波信号的频谱分析实操方波是实验中最经典的信号因为它的频谱有明确的解析表达式只包含奇次谐波第n次谐波的幅度与1/n成正比。这个理论结果和实验结果的对比是检验你操作是否正确的最好标准。实际操作中你需要注意几个点。第一方波的上升沿和下降沿在理论上都是瞬时的但实际生成的方波总有一定的上升时间这会导致高频成分的幅度比理论值略低。第二如果你用的方波不是整周期采样频谱泄漏会让谐波幅度出现偏差。我通常的做法是先取整数个周期比如10个周期用矩形窗做FFT这样泄漏最小。然后把理论值1/n和实验值画在同一张图上对比。如果前5次谐波的误差在5%以内说明你的操作是正确的。如果你发现谐波幅度衰减得比1/n快很多那很可能是采样率不够高频谐波被混叠或者被抗混叠滤波器衰减了。这时候你需要提高采样率重新做。4.3 矩形脉冲信号的频谱泄漏观察矩形脉冲信号是观察频谱泄漏的最佳载体。理论上一个宽度为τ的矩形脉冲其频谱是sinc函数主瓣宽度为2/τ旁瓣按1/f衰减。但在实际FFT中如果你截取的信号长度不是脉冲周期的整数倍频谱就会泄漏。具体表现是原本应该是sinc形状的频谱变成了很多根离散的谱线而且这些谱线的包络虽然还是sinc形状但谱线之间的间隔变成了Δf fs/N。这个实验的关键操作是故意改变截取长度观察频谱泄漏的变化。你可以先取整数个周期看到干净的sinc包络然后取非整数个周期看到泄漏产生的“裙边”。这个对比会让你对泄漏的成因有刻骨铭心的理解。注意矩形脉冲的频谱分析中脉冲宽度τ和频率分辨率Δf的关系很关键。如果τ 1/Δf也就是脉冲宽度小于一个频率分辨单元那么脉冲的能量会分散到整个频谱上你几乎看不到明显的sinc形状。这时候你需要增加N或者增加脉冲宽度。4.4 噪声环境下信号频谱的提取真实通信系统中信号总是淹没在噪声里的。这个环节的实验目的是让你体验“从噪声中提取信号”的过程。操作方法是先生成一个正弦波然后加上高斯白噪声信噪比从20dB逐渐降到-10dB。在每个信噪比下做FFT观察谱线是否还能从噪声基底中辨认出来。我实测下来的经验是对于单频正弦波当信噪比高于0dB时谱线在频谱图上清晰可见当信噪比降到-5dB时谱线开始和噪声混在一起需要仔细辨认当信噪比降到-10dB时单次FFT已经很难看到谱线了需要做多次平均。这个实验引出了一个重要的工程概念处理增益。FFT本身可以提供一定的处理增益因为信号能量集中在少数几个频率点上而噪声能量分散在整个频带。N点FFT的处理增益大约是10log10(N/2) dB。对于N1024处理增益约为27dB。这意味着即使信噪比是-20dB理论上你仍然可以通过FFT把信号检测出来。4.5 实验数据的记录与报告撰写实验报告不是把代码和截图贴上去就完事了。我见过太多实验报告就是“代码图一句结论”这种报告拿不到高分更重要的是你自己也没真正学到东西。一份好的实验报告应该包含参数选择的理由、中间过程的观察、异常现象的分析、以及和理论预期的对比。比如你选了fs40kHz你要说明为什么不是20kHz也不是100kHz你看到了频谱泄漏你要分析是哪个参数导致的你的实验结果和理论值有偏差你要解释偏差的来源。我通常建议在实验过程中随手记录每次改了什么参数、看到了什么变化、当时是怎么想的。这些记录比事后回忆要可靠得多而且写报告的时候直接整理这些记录就行效率高很多。5. 常见问题与排查技巧实录5.1 频谱图上出现莫名其妙的谱线这是最常见的问题。你明明只生成了一个1kHz的正弦波频谱图上却在3kHz、5kHz处也有谱线。这种情况通常有三个原因。第一个原因是信号生成函数本身的问题。比如你用np.sin(2*np.pi*f0*t)生成正弦波这没问题但如果你不小心用了方波函数或者三角波函数那当然会有谐波。检查你的信号生成代码。第二个原因是混叠。如果你的采样率不够高高频噪声或者信号的高次谐波会折叠到低频区域。解决方法很简单提高采样率或者在采样前加一个抗混叠滤波器。第三个原因是数值精度问题。MATLAB和Python的浮点数运算都有精度限制理论上应该是零的地方可能会出现很小的非零值。如果这些“伪谱线”的幅度比主谱线低60dB以上可以忽略如果只低20dB那就是真的有问题了。5.2 FFT结果和理论值对不上这个问题通常出在归一化上。我再强调一遍N点FFT的结果需要除以N/2才能得到单频信号的真实幅度。如果你忘了这一步幅度会大N/2倍。另一个常见原因是窗函数的影响。如果你加了汉宁窗窗函数的相干增益大约是0.5也就是说幅度会再小一半。你需要除以窗函数的相干增益来补偿。还有一个容易被忽视的点如果你分析的信号不是整周期采样谱线的峰值会落在两个频率点之间你看到的峰值幅度会比真实幅度低。这个损失叫做“扇贝损失”scalloping loss最大可以达到3.92dB对于矩形窗。解决方法是用更细的频率分辨率或者用插值算法估计真实峰值。5.3 频率分辨率不够导致谱线无法分辨当你需要分辨两个频率很接近的信号时频率分辨率就成了瓶颈。比如两个正弦波分别是1kHz和1.05kHz频率差是50Hz。如果你的Δf是39Hz理论上可以分辨但谱线会严重重叠很难准确读出两个峰值。提高频率分辨率的方法有两个增加FFT点数N或者增加信号观测时间T。但注意如果信号本身的持续时间不够长你只能通过补零来增加N而补零并不会真正提高分辨率。真正的分辨率取决于T N_original / fs补零只是让频谱曲线更平滑方便你找到峰值位置。我通常的做法是先根据需要的分辨率确定T然后根据T和fs确定N_original最后补零到2的整数次幂做FFT。这样既保证了分辨率又利用了FFT的高效算法。5.4 常见问题速查表问题现象可能原因排查方法解决方案频谱出现多余谱线信号本身含谐波检查信号生成代码改用纯正弦函数频谱出现多余谱线混叠提高fs观察是否消失提高采样率或加抗混叠滤波幅度值偏大未归一化检查是否除以N/2加归一化步骤幅度值偏小窗函数增益未补偿检查窗函数类型除以相干增益谱线模糊不清频率分辨率不足计算Δf fs/N增加N或T频谱泄漏严重非整周期采样检查信号周期与T的关系加窗或调整T低频段异常抬高直流分量未去除检查信号均值减去均值再FFT5.5 几个实验指导书上不会写的实操心得第一个心得先仿真再实测。如果你用的是硬件频谱仪先在MATLAB里把同样的信号仿真一遍心里有数了再去调仪器。这样你在仪器上看到异常时能立刻判断是仪器设置问题还是信号本身的问题。第二个心得保存原始数据。做实验的时候把时域采样数据保存成mat文件或者npy文件这样你事后想换一种分析方法不用重新做实验。我当年就是没保存数据后来想用不同的窗函数重新分析只能重做一遍实验。第三个心得注意频谱仪的参考电平设置。如果你用硬件频谱仪参考电平设得太高小信号看不到设得太低大信号会削顶。通常先把参考电平设得比预期最大幅度高10dB然后再根据实际情况调整。第四个心得多做几次平均。对于含噪声的信号单次FFT的频谱波动很大。做10次到100次平均频谱会平滑很多谱线也更清晰。MATLAB里可以用pwelch函数直接做平均周期图Python里可以用scipy.signal.welch。6. 从实验到工程频谱分析的延伸思考6.1 实验中学到的概念在实际系统中的应用信号频谱分析实验看起来只是一个基础实验但它涉及的概念在实际通信系统中无处不在。比如你学采样定理的时候觉得“采样率大于两倍最高频率”是一句废话但实际做软件无线电的时候射频前端的采样率选择直接决定了你能处理多宽的频带也决定了后续数字信号处理的复杂度。再比如窗函数的选择在OFDM系统中每个子载波的频谱是sinc形状如果子载波之间不满足正交条件就会产生子载波间干扰ICI。这个问题的本质和频谱泄漏是一样的解决方法也是类似的——通过加窗或者调整保护间隔来抑制。还有频率分辨率的问题在雷达信号处理中距离分辨率取决于信号带宽速度分辨率取决于观测时间。这和FFT中频率分辨率取决于观测时间的道理完全一致。你在这个实验里建立的直觉在后续课程和工作中会反复用到。6.2 频谱分析工具的演进与选择从最早的模拟频谱仪到后来的扫频式频谱仪再到现在的FFT频谱仪和实时频谱仪工具在变但核心原理没变。现在做实验MATLAB和Python已经足够但如果你以后从事射频测试或者电磁兼容相关工作还是需要熟悉硬件频谱仪的操作。软件方面除了MATLAB和Python还有一些开源工具值得了解。比如GNU Radio它把信号处理和频谱分析做成了可视化的模块适合做系统级的仿真。再比如一些在线FFT工具适合快速验证简单的信号但不适合做复杂的实验。我个人的建议是先把MATLAB或Python用熟这是最通用的工具。硬件频谱仪的操作可以等到实际工作需要时再学因为不同品牌、不同型号的仪器操作差异很大提前学意义不大。6.3 实验报告的进阶写法如果你想让实验报告脱颖而出可以在基本要求之外加一些扩展分析。比如对比不同窗函数的频谱泄漏抑制效果画出泄漏幅度随窗函数类型变化的曲线或者分析不同信噪比下FFT处理增益的实际值和理论值对比或者用频谱分析的方法测量一个未知信号的频率和幅度给出测量不确定度。这些扩展分析不需要很复杂但能体现你对实验内容的深入理解。我当年就是在基本实验之外加了一个“用FFT测量信号频率”的小节分析了频率测量精度和信噪比的关系最后实验报告拿了很高的分数。提示扩展分析的数据最好来自你自己的实验而不是抄别人的或者从网上找的。自己动手测出来的数据即使不够完美也比完美的抄袭数据有价值得多。6.4 后续实验的衔接与预习建议信号频谱分析实验之后通常紧接着是采样定理实验、滤波器设计实验、以及调制解调实验。这些实验都建立在频谱分析的基础之上。如果你在这个实验里把FFT、窗函数、频率分辨率这些概念搞清楚了后面的实验会轻松很多。我的建议是做完这个实验后不要急着写报告交差花半个小时把实验中的关键代码整理成一个函数库以后做其他实验可以直接调用。比如写一个plot_spectrum(x, fs, N_fft, window_type)函数输入时域信号和参数直接输出频谱图。这个函数库会伴随你整个通信原理课程的学习节省大量重复劳动的时间。另外如果你对频谱分析特别感兴趣可以提前了解一下功率谱密度PSD的概念。FFT得到的是幅度谱而PSD描述的是信号功率在频率上的分布在通信系统分析中更常用。MATLAB的pwelch函数和Python的scipy.signal.welch都是估计PSD的常用工具用法和FFT类似但输出的是功率而不是幅度。我在实际做通信系统仿真的时候几乎从来不用裸FFT都是用welch方法估计PSD。因为PSD的物理意义更明确而且对噪声的抑制效果更好。你可以在实验报告中加一个PSD分析的对比会让你的报告更有工程味道。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑