在正式进入FFT讲解之前,先来弄清楚下面几个概念很重要。
- 采样率(记为fs):每秒采样的点数,单位为Hz
- 采样间隔(dt):采样间隔为采样率的倒数,即dt = 1/fs;意思就是每采一个点需要多长时间
- 采样点数(N):N = fs * t
- 频率分辨力(
):
- 采样时间(t):采样N个点需要多长时间,即t = N/fs = 1/
对一个信号进行N点FFT之后,结果为N个点的复数。下面来说说复数的含义。
假设第n个采样点的值为a + b*i ,将该点的幅值记为An,相位记为Pn。
那么,有 ,
。
那么原始信号和FFT变换之后的信号有什么关系呢?
假设原始信号的幅度值为A,FFT的采样点数为N,那么有 。(由于FFT的结果具有对称性,所以这里n的范围取
)。当
时,
。
那么对应的原始信号的表达式为 ,
那么下面就来看看由FFT的结果能不能推导出原始信号?
先给出代码
%% FFT小实验
%功能:帮助理解FFT的物理意义
%2019年8月16日15:02:20
close all;clc;clear all;
fs = 256;%采样率
N = 256;%采样点数
delta_f = fs/N;%频率分辨率
t = (0:1/fs:N/fs);%1/fs代表采样间隔, N/fs表示采样时间
%% 模拟一个信号,参数设置如下
Adc = 2;%直流分量
A1 = 3;%信号1的幅值、频率和相位
f1 = 50;
p1 = 30;
A2 = 1.5;%信号2的幅值、频率和相位
f2 = 75;
p2 = 90;
St = Adc + A1*cos(2*pi*f1*t - pi*p1/180) + A2*cos(2*pi*f2*t + pi*p2/180);
%% 绘图
figure
plot(St);
title('时域波形')
figure
res_fft = fft(St,N);
abs_res_fft = abs(res_fft);
plot(abs_res_fft);
title('一维FFT结果')
%真实的幅度和频率
real_amp = abs_res_fft/(N/2);
real_amp(1) = abs_res_fft(1)/N;
real_freq = ((1:N)-1)*fs/N;
figure
plot(real_freq,real_amp)
title('真实的幅值和频率')
xlabel('频率')
ylabel('幅度')
%真实的相位
figure;
Phrase=(1:N/2);
for i=1:N/2
Phrase(i)=phase(res_fft(i)); %计算相位
Phrase(i)=Phrase(i)*180/pi; %换算为角度
end
plot(real_freq(1:N/2),Phrase(1:N/2)); %显示相位图
title('相位-频率曲线图');
xlabel('频率')
ylabel('相位')
实验结果分析
频率是否一致?
因为信号的fs = 256Hz ,N = 256 ,所以频率分辨率为1Hz 。原始信号包含直流分量,50Hz,以及75Hz三个频率分量,由
可推测得知,对应的FFT之后的点分别位于第1点,第51点和第76点。【推测】
那么事实的情况是什么样子的呢? 如下图所示,为FFT之后的部分结果【实验结果】
第1点附近的值
第51点附近的值
第76点附近的值
从上面可以看出,只有第1,51,76点的值比较大,它们附近的值都比较小,可以近似为0。可以得出【推测】和【实验结果】在信号的频率上是一致的。
有个点需要注意一下:如何提高频率分辨率?(值越小,代表频率分辨率越好)
当fs = 1024Hz,N = 1204时,对应的频率分辨率为1Hz,采样时间维1s;
当fs = 1024Hz,N = 2048时,对应的频率分辨率为0.5Hz,采样时间为2s。
想要增加频率分辨率,就要增加采样点数,也就是要增加采样时间。但是在工程应用中,一般用小的采样时间,然后在信号后面补0的方式在一定程度上提高频率分辨率。
幅度是否一致?
由下图可以看出FFT后的幅度值和原始信号幅度值之间的关系和我们的理论推导是一致的。
相位是否一致?
由下图可以看出FFT后的相位值和原始信号相位也是一致的。