游乐游手机版
首页/AI热点日报/热点详情

FFT快速傅里叶变换原理解析零基础入门教程

类型:热点整理2026-07-11
频域分析原理 先聊一个大家都熟悉的场景:卡拉OK的音频频谱显示。那不断跳动的柱状图,横轴是频率,纵轴是功率,能实时反映声音的“成分”。这背后,核心算法就是FFT(快速傅里叶变换)。 举个小例子,比如在VR单片机项目中用FFT分析语音信号,视频里就能直观看到频谱实时跳动的效果。 FFT本质上是DFT(

频域分析原理

先聊一个大家都熟悉的场景:卡拉OK的音频频谱显示。那不断跳动的柱状图,横轴是频率,纵轴是功率,能实时反映声音的“成分”。这背后,核心算法就是FFT(快速傅里叶变换)。

举个小例子,比如在VR单片机项目中用FFT分析语音信号,视频里就能直观看到频谱实时跳动的效果。

FFT本质上是DFT(离散傅里叶变换)的“加速版”。1965年,Cooley和Tukey将其正式推向应用,此后各种优化技巧都围绕着同一个目标:减少乘法运算量。DFT的计算复杂度是O(N²),而FFT降到了O(N log₂N)。这意味着什么?随着采样点数N的增大,FFT的计算优势会越来越显著。

那么DFT到底是如何工作的?可以简单理解成一个“频率探测器”。

假设我们有一段用fs采样得到的N点数字序列A,里面隐藏了一个频率为fa的正弦波,但我们不知道它的幅度和相位。该怎么办?

方法就是利用“信号相关”。我们构造两个频率也为fa、幅度为1的标准信号:一个正弦波B,一个余弦波C。然后用B和C分别与原始序列A做乘法,再将结果进行滤波(通常就是求平均)。

有趣的地方来了:如果A里只包含fa这个频率的信号,相乘滤波后,结果不为零,我们能由此计算出幅度和相位。而如果A里还有其他频率的成分,经过同样的处理,输出结果正好是零——相当于被完美滤除了。

用公式来表达就是:

A信号序列为: x[n]

B信号序列为: cos(2π·fa·n·ts)

C信号序列为: sin(2π·fa·n·ts)

那么两个输出经过滤波(求平均)后的结果是:

I = (1/N) * Σ(x[n] * cos(2π·fa·n·ts))

Q = (1/N) * Σ(x[n] * sin(2π·fa·n·ts))

通过(I, Q)这对值,就可以反推出信号的幅度和相位:

幅度 = 2 * sqrt(I² + Q²)

相位 = arctan(Q / I)

这里有一个关键前提:当N点序列计算结束时,正弦和余弦信号的相位必须是2π的整数倍。这样滤波器才能把其他频率分量“彻底清零”,避免出现频谱泄露。

为了保证这一点,fa必须满足:fa * N * ts 是整数。换句话说,fa = k * (fs / N),其中k是整数。这就是为什么进行N点DFT时,只有频率正好是fs/N的整数倍,才能完美地“锁定”这个信号,不产生泄露。

程序验证

光说理论有点抽象,直接上代码来验证。下面是用MATLAB实现的一个简单FFT仿真:

% FFT计算示例
fa   = 200.1953125e6;     % 信号频率,不产生频谱混叠
A0   = 1;                 % 信号幅度
fs   = 1e9;               % 采样率
Nfft = 1024;              % FFT点数
wa   = 2*pi*fa;
ts   = 1/fs;
t    = 0:ts:ts*(Nfft-1);   % 构造时间序列
Vn   = 1e-3*randn(1,Nfft); % 添加小噪声
y    = A0*sin(wa*t)+Vn;    % 合成信号
X    = fft(y, Nfft);       % 计算FFT
Amp  = 2*abs(X)/Nfft;      % 计算幅度
Amp_log = 20*log10(Amp);   % 转换为dB
f    = linspace(0, fs/2, Nfft/2+1)*1e-6;
plot(f, Amp_log(1:Nfft/2+1), '-r', 'LineWidth', 1);
grid on;
ylim([-100,10]);
ylabel('Amp/dBFS');
xlabel('freq/MHz');
title(sprintf('FFT, fs=%0.2fM Hz, fa=%0.8fM Hz', fs*1e-6,fa*1e-6));

仿真结果非常直观:

设置fa=200.1953125MHz,结果频谱上只有一个干净的尖峰:

一切正常,信号能量完美集中在这个频点。

但如果把fa改成正好的200.0000000MHz,情况就发生了变化:

可以看到,能量不再集中在单一频点,而是“摊”开了——这就是典型的频谱泄露现象。想想看,如果fa刚好是fs/N的整数倍,问题就不存在了。这里200MHz不是fs/N(fs/N = 1e9/1024,计算得约976562.5Hz)的整数倍,泄露自然就出现了。

小程序实现

专门用来处理这个问题的小程序,可以帮你计算:给定一个信号频率,找出最接近它、且能保证不出现频谱泄露的那个“安全”频率。举个例子,输入200MHz,它返回的就是最接近的、没有泄露问题的频率点:

还能算出一个FFT Bin(频率“小格子”)的精确带宽:

更贴心的是,这个小程序还会告诉你当前信号落在了哪一奈奎斯特区域:

可以看到,这个fa信号处于第二奈奎斯特区域。了解这一点,有助于判断信号是否发生混叠,以及在后级处理中如何正确“折叠”频谱。这样的工具,对从事数字信号处理的人来说,能省下不少精力。

来源:https://m.elecfans.com/article/2072468.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。