恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
信号频谱分析实验:从FFT原理到窗函数与混叠的工程实践
首页
资讯中心
/
信号频谱分析实验:从FFT原理到窗函数与混叠的工程实践
信号频谱分析实验:从FFT原理到窗函数与混叠的工程实践
发布时间:2026/10/14 1:07:42
1. 信号频谱分析到底在分析什么1.1 从“看不见的信号”到“看得见的频谱”做数字通信实验第一个绕不开的坎就是信号频谱分析。很多同学拿到实验箱或者打开仿真软件的那一刻是懵的——示波器上明明能看到正弦波、方波、矩形脉冲为什么还要费劲去搞一个频谱答案很简单时域看到的是信号随时间变化的波形频域看到的才是信号由哪些频率成分构成。这两个视角缺一不可而通信系统里几乎所有关键决策——带宽分配、滤波器设计、调制方式选择——都依赖频域信息。打个比方时域波形就像一首曲子从头到尾的演奏过程频谱则像乐谱上标明的每一个音符。你光听演奏很难说清楚里面有几个乐器、各自什么音高但一看乐谱所有成分一目了然。信号频谱分析实验要干的事情就是用数学工具和仪器把“乐谱”画出来。这个实验通常面向通信工程、电子信息工程专业的本科生一般在数字通信原理课程进行到第三章左右开设。前置知识包括傅里叶级数、傅里叶变换、抽样定理以及基本的MATLAB或Python编程能力。如果你这些基础还不太扎实也不用慌实验本身会帮你把抽象公式和实际波形对应起来做一遍比看十遍书管用。1.2 这个实验能解决哪些实际问题频谱分析不是纸上谈兵。在实际工程中至少有三类问题必须靠频谱分析来解决第一判断信号占用了多少带宽。比如你要设计一个滤波器把某个信号滤出来首先得知道它的频谱范围。如果连信号能量集中在哪个频段都不清楚滤波器参数根本没法设。第二发现谐波和杂散成分。一个理想方波的频谱是离散的奇次谐波但实际电路产生的方波可能带有偶次谐波或者非整数倍频率的杂散这些往往意味着电路存在问题。频谱分析能帮你快速定位。第三验证调制效果。做AM、FM或者数字调制实验时调制是否成功、边带是否对称、载波抑制是否到位都要看频谱。时域波形可能看起来“差不多”但频谱一出来问题无处遁形。所以这个实验的价值不在于“完成一个作业”而在于建立一种思维方式遇到任何信号处理问题先想它的频谱长什么样。这个习惯一旦养成后面做滤波器、采样、调制解调都会顺畅很多。1.3 实验的核心目标与预期产出具体到“信号频谱分析实验”这个标题核心目标可以拆成三条掌握用傅里叶变换求信号频谱的数学方法能手工推导典型信号正弦、方波、矩形脉冲、三角波的频谱表达式。能使用MATLAB或Python编写程序对上述信号进行频谱分析正确绘制幅度谱和相位谱。理解抽样率、频率分辨率、窗函数对频谱分析结果的影响能解释实验中出现的频谱泄漏、混叠等现象。预期产出通常包括实验报告含理论推导、代码、频谱图、结果分析和一份可复现的代码文件。有些学校还要求用实验箱配合频谱仪实测但纯仿真版本已经能覆盖90%的核心知识点。注意很多同学做这个实验时只关心“图画出来没有”不关心“图对不对”。频谱分析最忌讳的就是图看起来漂亮但参数设错了。比如抽样率选得太低导致混叠频谱上会出现根本不存在的频率成分你还以为发现了新信号。2. 实验前的理论准备与工具选型2.1 傅里叶变换从公式到直觉傅里叶变换的公式大家都背过[ X(f) \int_{-\infty}^{\infty} x(t) e^{-j2\pi ft} dt ]但光背公式没用得知道它在干什么。这个积分本质上是在问一个问题信号x(t)里面频率为f的成分有多少。它把信号和不同频率的复指数函数做内积内积大就说明这个频率成分强内积小就说明弱。对于周期信号用傅里叶级数更方便[ x(t) \sum_{n-\infty}^{\infty} c_n e^{j2\pi n f_0 t} ]其中 ( c_n ) 是第n次谐波的复振幅( f_0 ) 是基频。周期信号的频谱是离散的只在 ( n f_0 ) 处有值。非周期信号则用傅里叶变换频谱是连续的。实验里最常打交道的几个信号它们的频谱必须做到“不查表就能写出来”信号类型时域表达式频谱特点正弦波( A\sin(2\pi f_0 t) )只在 ( \pm f_0 ) 处有冲激幅度 ( A/2 )方波周期为T幅度±A奇次谐波幅度按 ( 1/n ) 衰减矩形脉冲宽度τ幅度A辛格函数 ( A\tau \text{sinc}(f\tau) )三角波周期为T幅度±A奇次谐波幅度按 ( 1/n^2 ) 衰减提示方波和三角波的谐波衰减速度不同这是实验里区分它们频谱的重要特征。方波衰减慢1/n三角波衰减快1/n²所以三角波看起来更“干净”。2.2 抽样率与频率分辨率两个最容易踩坑的参数做数字频谱分析绕不开两个参数抽样率 ( f_s ) 和频率分辨率 ( \Delta f )。抽样率决定了你能分析的最高频率。根据奈奎斯特抽样定理( f_s ) 必须大于信号最高频率的两倍否则会发生混叠。比如你要分析一个最高频率为1kHz的信号抽样率至少得2000Hz实际工程中通常取5到10倍即5kHz到10kHz留足余量。频率分辨率决定了频谱图上两个相邻点之间的频率间隔。如果做N点FFT抽样率为 ( f_s )则[ \Delta f \frac{f_s}{N} ]这个公式说明要提高频率分辨率即减小Δf要么降低抽样率要么增加FFT点数。但降低抽样率受奈奎斯特定理限制所以通常靠增加N来实现。比如 ( f_s 10kHz )N1024则 ( \Delta f \approx 9.77Hz )如果N4096则 ( \Delta f \approx 2.44Hz )。这里有个常见的误解有人以为补零能提高频率分辨率。补零确实能让频谱图上的点变密但那些新增的点是插值出来的不是真正的分辨率提升。真正的分辨率只取决于实际观测时间 ( T N/f_s )分辨率 ( \Delta f 1/T )。补零只是让曲线看起来更光滑不会让你分辨出两个靠得很近的频率成分。2.3 工具选型MATLAB还是Python实验工具无非两种MATLAB和Python。两者都能做但各有优劣。MATLAB的优势在于信号处理工具箱成熟fft、pwelch、spectrogram这些函数开箱即用绘图也方便。很多学校的实验指导书默认用MATLAB代码可以直接抄。缺点是正版授权费用高学生版有功能限制。Python的优势是免费开源numpy.fft和scipy.signal功能足够强大matplotlib绘图灵活。缺点是环境配置对新手不太友好而且网上代码质量参差不齐容易抄到有bug的版本。我的建议是如果学校提供了MATLAB就用MATLAB省事如果自己想长期用学Python更划算。下面两套代码我都会给你可以按需选择。不管用哪个工具核心逻辑是一样的生成信号→加窗→FFT→取模→绘图。区别只在函数名和语法。2.4 窗函数为什么需要它怎么选做FFT时我们实际上只截取了信号的一段时间片段。这个截断操作相当于给信号乘了一个矩形窗。矩形窗的频谱是辛格函数有较大的旁瓣会导致频谱泄漏——原本应该集中在某个频率的能量泄漏到了邻近频率。解决方法是换一个旁瓣更小的窗函数。常用的窗函数有矩形窗主瓣最窄但旁瓣最高-13dB适合信号频率正好落在FFT频点上且信噪比高的情况。汉宁窗旁瓣低-31dB主瓣稍宽适合一般性频谱分析。汉明窗旁瓣更低-41dB但旁瓣衰减慢适合需要低旁瓣的场合。布莱克曼窗旁瓣极低-57dB主瓣最宽适合弱信号检测。选择窗函数的原则是如果信号频率未知或不是FFT频点的整数倍用汉宁窗或汉明窗如果信号频率已知且正好落在频点上用矩形窗。实验里为了观察泄漏现象通常会故意用矩形窗然后换汉宁窗对比效果。注意加窗会降低频谱幅度需要在计算时做归一化补偿。不同窗函数的补偿系数不同汉宁窗的幅度补偿系数约为2汉明窗约为1.85。如果忘了补偿频谱幅度会偏小导致你误判信号功率。3. 完整实操流程与代码实现3.1 实验环境搭建与基础参数设定先确定实验的基本参数。假设我们要分析一个由多个正弦分量组成的信号频率分别为100Hz、200Hz、350Hz幅度分别为1、0.5、0.3。抽样率取2000Hz观测时间0.5秒则采样点数N1000。为什么选这些参数100Hz到350Hz的频率范围2000Hz抽样率满足奈奎斯特条件最高频率350Hz2倍是700Hz2000Hz远大于700Hz。观测时间0.5秒对应频率分辨率 ( \Delta f 1/0.5 2Hz )足以分辨100Hz和200Hz间隔100Hz也能分辨200Hz和350Hz间隔150Hz。如果两个频率间隔小于2Hz就需要增加观测时间。MATLAB环境准备很简单确保安装了Signal Processing Toolbox即可。Python需要安装numpy、scipy、matplotlibpip install numpy scipy matplotlib3.2 生成测试信号并观察时域波形先写代码生成信号。MATLAB版本fs 2000; % 抽样率 T 0.5; % 观测时间 t 0:1/fs:T-1/fs; % 时间向量 f1 100; f2 200; f3 350; A1 1; A2 0.5; A3 0.3; x A1*sin(2*pi*f1*t) A2*sin(2*pi*f2*t) A3*sin(2*pi*f3*t); plot(t, x); xlabel(时间 (s)); ylabel(幅度); title(时域波形); xlim([0 0.05]); % 只看前0.05秒否则太密看不清Python版本import numpy as np import matplotlib.pyplot as plt fs 2000 T 0.5 t np.arange(0, T, 1/fs) f1, f2, f3 100, 200, 350 A1, A2, A3 1, 0.5, 0.3 x A1*np.sin(2*np.pi*f1*t) A2*np.sin(2*np.pi*f2*t) A3*np.sin(2*np.pi*f3*t) plt.plot(t, x) plt.xlabel(时间 (s)) plt.ylabel(幅度) plt.title(时域波形) plt.xlim(0, 0.05) plt.show()时域波形看起来是三个正弦波叠加的结果周期约为0.01秒对应100Hz但波形不是纯正弦有明显的“毛刺”说明含有高频成分。光看时域你很难说清楚到底有几个频率成分这就是为什么要转到频域。3.3 用FFT计算频谱并正确绘图接下来做FFT。MATLAB里直接用fft函数N length(x); X fft(x); X_mag abs(X)/N; % 归一化幅度 X_mag X_mag(1:N/21); % 取单边谱 X_mag(2:end-1) 2*X_mag(2:end-1); % 除直流和奈奎斯特外幅度乘2 f (0:N/2)*fs/N; % 频率轴 plot(f, X_mag); xlabel(频率 (Hz)); ylabel(幅度); title(幅度谱); xlim([0 500]);Python版本N len(x) X np.fft.fft(x) X_mag np.abs(X)/N X_mag X_mag[:N//21] X_mag[1:-1] 2*X_mag[1:-1] f np.arange(0, N//21)*fs/N plt.plot(f, X_mag) plt.xlabel(频率 (Hz)) plt.ylabel(幅度) plt.title(幅度谱) plt.xlim(0, 500) plt.show()这里有几个关键点必须解释清楚为什么除以NFFT输出的幅度和信号长度有关除以N是为了归一化让正弦波的幅度谱峰值等于其实际幅度。如果不除峰值会随N变化没法比较。为什么取单边谱实信号的频谱是对称的正频率和负频率各有一半能量。取单边谱后除了直流和奈奎斯特频率其他频率的幅度要乘2才能保持总能量不变。为什么频率轴是(0:N/2)*fs/NFFT输出的第k个点对应频率 ( k \cdot f_s / N )。取前N/21个点对应0到 ( f_s/2 )即奈奎斯特频率。运行后应该看到三个峰值分别在100Hz、200Hz、350Hz处幅度分别为1、0.5、0.3。如果峰值位置或幅度不对检查抽样率、信号频率、归一化步骤。3.4 观察频谱泄漏并对比窗函数效果现在故意制造频谱泄漏。把信号频率改成105Hz、205Hz、355Hz这些频率不是 ( \Delta f 2Hz ) 的整数倍。用矩形窗即不加窗做FFT你会看到峰值周围出现“裙边”能量泄漏到了邻近频率。然后加汉宁窗w hanning(N); xw x .* w; Xw fft(xw); Xw_mag abs(Xw)/N; Xw_mag Xw_mag(1:N/21); Xw_mag(2:end-1) 2*Xw_mag(2:end-1); % 汉宁窗幅度补偿 Xw_mag Xw_mag * 2; plot(f, Xw_mag);Python版本w np.hanning(N) xw x * w Xw np.fft.fft(xw) Xw_mag np.abs(Xw)/N Xw_mag Xw_mag[:N//21] Xw_mag[1:-1] 2*Xw_mag[1:-1] Xw_mag Xw_mag * 2 # 汉宁窗补偿 plt.plot(f, Xw_mag)对比两张图加汉宁窗后泄漏明显减小峰值更干净但主瓣变宽了。这就是窗函数选择的权衡旁瓣抑制越好主瓣越宽频率分辨率越低。实验报告里应该把这个权衡关系写清楚。提示汉宁窗的幅度补偿系数是2汉明窗是1.85布莱克曼窗是2.38。如果补偿系数用错幅度会有10%到20%的误差在定量分析中不可接受。3.5 验证抽样定理与混叠现象最后做一个混叠实验。把信号频率改成1200Hz抽样率仍然是2000Hz。根据奈奎斯特定理1200Hz超过了 ( f_s/2 1000Hz )应该发生混叠。实际频谱上会出现一个200Hz的峰值因为1200 - 1000 200或者1000 - (1200-1000) 800取决于相位。运行代码验证f_alias 1200; x_alias sin(2*pi*f_alias*t); X_alias fft(x_alias); X_alias_mag abs(X_alias)/N; X_alias_mag X_alias_mag(1:N/21); X_alias_mag(2:end-1) 2*X_alias_mag(2:end-1); plot(f, X_alias_mag); xlim([0 500]);你会看到峰值出现在200Hz处而不是1200Hz。这就是混叠——高频信号“伪装”成了低频信号。如果实际系统中出现这种情况会导致严重的误判。解决办法是加抗混叠滤波器在抽样前把高于 ( f_s/2 ) 的频率成分滤掉。4. 常见问题与排查技巧实录4.1 频谱峰值位置不对怎么办这是最常见的问题。峰值位置偏移通常有三个原因原因一频率轴计算错误。检查频率轴是不是(0:N/2)*fs/N。有人误写成(0:N-1)*fs/N导致频率范围变成0到 ( f_s )峰值位置翻倍。原因二抽样率设置错误。比如实际抽样率是2000Hz代码里写成了1000Hz峰值位置会偏大一倍。检查fs变量是否和信号生成时一致。原因三信号频率本身不是整数。比如你想生成100Hz但代码里写了sin(2*pi*100*t)而t的步长不是1/fs的整数倍导致实际频率有微小偏差。确保t 0:1/fs:T-1/fs。排查方法先做一个单频信号测试比如只生成100Hz正弦波看峰值是否在100Hz。如果不对逐项检查上述三个原因。4.2 频谱幅度和理论值对不上幅度误差通常来自归一化和窗函数补偿。常见错误包括忘了除以N导致幅度随N变化。忘了单边谱乘2导致幅度只有理论值的一半。加窗后忘了补偿导致幅度偏小。信号本身有直流分量导致直流处有峰值干扰判断。排查方法用纯正弦波测试幅度设为1看频谱峰值是否接近1。如果差一倍检查单边谱乘2如果差两倍以上检查归一化和窗补偿。4.3 频谱出现不该有的频率成分如果频谱上出现了信号中不存在的频率通常是以下原因混叠。信号最高频率超过 ( f_s/2 )高频成分混叠到了低频。解决办法是提高抽样率或加抗混叠滤波器。频谱泄漏。信号频率不是 ( \Delta f ) 的整数倍能量泄漏到了邻近频点。这不是“错误”而是FFT的固有特性。加窗可以减轻但不能完全消除。电源干扰。如果做实物实验50Hz工频干扰会出现在频谱上。检查接地和屏蔽。量化噪声。如果信号经过ADC量化噪声会均匀分布在频谱上表现为底噪抬高。增加量化位数可以改善。4.4 常见问题速查表现象可能原因排查方法解决办法峰值位置偏移频率轴错误检查频率轴公式改为(0:N/2)*fs/N峰值位置偏移抽样率不一致检查fs变量统一信号生成和FFT的fs幅度偏小一半未做单边谱乘2检查归一化步骤除直流和奈奎斯特外乘2幅度随N变化未除以N检查是否除以N加abs(X)/N频谱有裙边频谱泄漏检查信号频率是否为Δf整数倍加汉宁窗或汉明窗出现不存在的频率混叠检查最高频率是否超fs/2提高fs或加抗混叠滤波底噪抬高量化噪声检查ADC位数增加量化位数50Hz处有峰值工频干扰检查接地改善屏蔽和接地4.5 几个容易被忽略的实操心得心得一先做单频再做多频。很多同学一上来就生成复杂信号结果出了问题不知道是哪个环节的错。先用单频正弦波验证整个流程确认频谱峰值位置和幅度都对再逐步增加频率成分。这样出问题时容易定位。心得二频谱图一定要标坐标轴和单位。我见过太多实验报告图是画出来了但横轴没标“频率(Hz)”纵轴没标“幅度”读者根本不知道你在说什么。养成好习惯每张图都标清楚。心得三保存代码和参数。实验报告里的图可能被要求重画如果代码没保存就得从头再来。建议把代码、参数、生成的图放在一个文件夹里命名清晰比如spectrum_analysis_v1.m、spectrum_analysis_v1.png。心得四用pwelch做功率谱密度估计。如果信号是随机信号或者信噪比很低直接用FFT看幅度谱可能不够。MATLAB的pwelch函数用Welch方法做功率谱密度估计通过分段平均降低方差频谱更平滑。Python里对应scipy.signal.welch。这个技巧在做噪声分析时特别有用。心得五注意FFT的对称性。实信号的FFT输出是共轭对称的即 ( X[k] X^*[N-k] )。如果你看到频谱关于 ( f_s/2 ) 对称那是正常的。取单边谱时只取前一半不要重复计算。心得六频率分辨率不是越高越好。提高频率分辨率需要增加观测时间但观测时间太长会导致信号非平稳比如频率漂移反而使频谱模糊。实际工程中要根据信号特性折中。对于稳态信号观测时间可以长一些对于瞬态信号观测时间要短否则信号已经结束了后面全是零。心得七相位谱同样重要。很多实验只关注幅度谱忽略了相位谱。但在通信系统中相位信息往往携带关键信息。比如QPSK调制幅度谱看起来差不多但相位谱能区分不同的符号。做实验时不妨把相位谱也画出来看看不同信号的相位特性。心得八用对数坐标看动态范围。如果信号动态范围很大比如强信号和弱信号共存线性坐标下弱信号可能被淹没。改用对数坐标dB能同时看清强信号和弱信号。MATLAB里用20*log10(X_mag)Python里用20*np.log10(X_mag)。注意幅度为0时对数会出负无穷加一个小量比如1e-12避免。心得九实验箱实测时注意探头衰减。如果用实验箱配合频谱仪实测探头可能有10:1或100:1的衰减。忘了乘衰减系数幅度会差10倍或100倍。实测前先用已知幅度的信号校准。心得十多对比多记录。实验的价值在于对比。同一信号用不同窗函数、不同抽样率、不同FFT点数各做一遍把图放在一起对比你才能真正理解每个参数的影响。实验报告里把这些对比图放上去比只放一张“正确”的图有价值得多。5. 从实验到工程频谱分析的延伸应用5.1 滤波器设计中的频谱分析做完这个实验你其实已经具备了设计滤波器的基本能力。滤波器设计的核心就是看信号的频谱确定通带和阻带然后选择滤波器类型和阶数。比如你要从混合信号中提取100Hz成分滤除200Hz和350Hz看频谱就知道通带截止频率应该设在150Hz左右阻带截止频率设在180Hz左右。然后用巴特沃斯、切比雪夫或椭圆滤波器逼近这个指标。MATLAB里用fdatool或designfiltPython里用scipy.signal.butter和scipy.signal.filtfilt。设计完滤波器后再对信号做一次频谱分析看滤波后的频谱是否满足要求。这个“分析-设计-验证”的闭环就是数字信号处理的基本工作流。5.2 调制解调中的频谱观察数字通信里调制就是把基带信号的频谱搬移到载波频率附近。做AM调制时频谱上会出现载波和两个边带做FM调制时频谱上会出现无穷多个边带但主要能量集中在载波附近。做数字调制如ASK、FSK、PSK时频谱的形状和符号速率、脉冲成型滤波器有关。如果你继续做后续实验会发现频谱分析是验证调制效果的最直接手段。比如QPSK调制理想情况下频谱应该关于载波对称如果不对称说明I路和Q路不平衡。这些细节在时域波形上很难发现但频谱上一目了然。5.3 用频谱分析排查实际电路问题实际电路中很多问题都会在频谱上留下痕迹。比如放大器自激频谱上出现高频尖峰频率通常是某个寄生振荡频率。电源纹波频谱上出现100Hz或120Hz的峰值取决于电源频率和整流方式。时钟馈通频谱上出现时钟频率及其谐波。接地环路频谱上出现50Hz及其谐波。学会看频谱你就多了一个排查电路问题的利器。很多老工程师修电路第一件事就是接频谱仪看频谱比万用表还快。5.4 后续学习路径建议如果你对这个实验感兴趣想继续深入建议按以下路径学习数字滤波器设计FIR和IIR滤波器的设计方法用MATLAB或Python实现。抽样率转换内插和抽取多相滤波器结构。功率谱估计周期图法、Welch法、AR模型法。时频分析短时傅里叶变换、小波变换用于非平稳信号分析。通信系统仿真用Simulink或Python搭建完整的调制解调链路观察各节点的频谱。这些内容在后续课程和项目中都会用到。频谱分析是基础中的基础把这个实验做扎实后面会轻松很多。我个人在实际操作中的体会是频谱分析实验最大的价值不是学会用fft函数而是建立“频域思维”。一旦你习惯从频域看问题很多时域上复杂的事情会变得简单。比如两个信号叠加时域上看是波形相加频域上看就是频谱相加哪个频率成分强、哪个弱一目了然。这种思维方式在后续做滤波器、调制解调、信道均衡时都会反复用到。所以实验报告不要只贴代码和图把你在频域上观察到的现象和时域上的对应关系写清楚这才是实验报告最有价值的部分。