MATLAB中FFT的使用方法.docx
- 文档编号:9997667
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:13
- 大小:186.99KB
MATLAB中FFT的使用方法.docx
《MATLAB中FFT的使用方法.docx》由会员分享,可在线阅读,更多相关《MATLAB中FFT的使用方法.docx(13页珍藏版)》请在冰豆网上搜索。
MATLAB中FFT的使用方法
MATLAB中FFT的使用方法
调用方法
X=FFT(x);
X=FFT(x,N);%N为FFT后的数据点数,如果实际信号的数据点数小于N的话,则需要在FFT变换时增加采样点数,或者通过采用频率细分法在原数据后面补充一定数量的0,从而满足N个数据点
X=IFFT(X);
X=IFFT(X,N)
一、用MATLAB进行谱分析时注意:
(1)函数FFT返回值的数据结构具有对称性。
例:
N=8;
n=0:
N-1;
xn=[43267890];
Xk=fft(xn)
Xk=
39.0000 -10.7782+6.2929i 0-5.0000i 4.7782-7.7071i 5.0000 4.7782+7.7071i 0+5.0000i-10.7782-6.2929i
Xk与xn的维数相同,共有8个元素。
Xk的第一个数对应于直流分量,即频率值为0。
(2)做FFT分析时,幅值大小与FFT选择的点数有关,但不影响分析结果。
在IFFT时已经做了处理。
要得到真实的振幅值的大小,只要将得到的变换后结果乘以2除以N即可。
二、FFT应用举例
例1:
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t)。
采样频率fs=100Hz,分别绘制N=128、1024点幅频图。
clf;
fs=100;N=128; %采样频率和数据点数
n=0:
N-1;t=n/fs; %时间序列
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t);%信号
y=fft(x,N); %对信号进行快速Fourier变换
mag=abs(y); %求得Fourier变换后的振幅
f=n*fs/N; %频率序列
subplot(2,2,1),plot(f,mag); %绘出随频率变化的振幅
xlabel('频率/Hz');
ylabel('振幅');title('N=128');gridon;
subplot(2,2,2),plot(f(1:
N/2),mag(1:
N/2));%绘出Nyquist频率之前随频率变化的振幅
xlabel('频率/Hz');
ylabel('振幅');title('N=128');gridon;
%对信号采样数据为1024点的处理
fs=100;
N=1024;
n=0:
N-1;
t=n/fs;
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t);%信号
y=fft(x,N); %对信号进行快速Fourier变换
mag=abs(y); %求取Fourier变换的振幅
f=n*fs/N;
subplot(2,2,3),
plot(f,mag);%绘出随频率变化的振幅
xlabel('频率/Hz');
ylabel('振幅');
title('N=1024');
gridon;
subplot(2,2,4)
plot(f(1:
N/2),mag(1:
N/2));%绘出Nyquist频率之前随频率变化的振幅
xlabel('频率/Hz');
ylabel('振幅');
title('N=1024');
gridon;
运行结果:
fs=100Hz,Nyquist频率为fs/2=50Hz。
整个频谱图是以Nyquist频率为对称轴的。
并且可以明显识别出信号中含有两种频率成分:
15Hz和40Hz。
由此可以知道FFT变换数据的对称性。
因此用FFT对信号做谱分析,只需考察0~Nyquist频率范围内的幅频特性。
若没有给出采样频率和采样间隔,则分析通常对归一化频率0~1进行。
另外,振幅的大小与所用采样点数有关,采用128点和1024点的相同频率的振幅是有不同的表现值,但在同一幅图中,40Hz与15Hz振动幅值之比均为4:
1,与真实振幅0.5:
2是一致的。
为了与真实振幅对应,需要将变换后结果乘以2除以N。
例2:
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t),fs=100Hz,绘制:
(1)数据个数N=32,FFT所用的采样点数NFFT=32;
(2)N=32,NFFT=128;
(3)N=136,NFFT=128;
(4)N=136,NFFT=512。
clf;
fs=100;%采样频率
Ndata=32;%数据长度
N=32;%FFT的数据长度
n=0:
Ndata-1;
t=n/fs; %数据对应的时间序列
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t); %时间域信号
y=fft(x,N); %信号的Fourier变换
mag=abs(y); %求取振幅
f=(0:
N-1)*fs/N;%真实频率
subplot(2,2,1),plot(f(1:
N/2),mag(1:
N/2)*2/N);%绘出Nyquist频率之前的振幅
xlabel('频率/Hz');ylabel('振幅');
title('Ndata=32Nfft=32');gridon;
Ndata=32; %数据个数
N=128; %FFT采用的数据长度
n=0:
Ndata-1;t=n/fs; %时间序列
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t);
y=fft(x,N);
mag=abs(y);
f=(0:
N-1)*fs/N;%真实频率
subplot(2,2,2),plot(f(1:
N/2),mag(1:
N/2)*2/N);%绘出Nyquist频率之前的振幅
xlabel('频率/Hz');ylabel('振幅');
title('Ndata=32Nfft=128');gridon;
Ndata=136; %数据个数
N=128; %FFT采用的数据个数
n=0:
Ndata-1;t=n/fs;%时间序列
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t);
y=fft(x,N);
mag=abs(y);
f=(0:
N-1)*fs/N; %真实频率
subplot(2,2,3),plot(f(1:
N/2),mag(1:
N/2)*2/N);%绘出Nyquist频率之前的振幅
xlabel('频率/Hz');ylabel('振幅');
title('Ndata=136Nfft=128');
gridon;
Ndata=136; %数据个数
N=512; %FFT所用的数据个数
n=0:
Ndata-1;t=n/fs;%时间序列
x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t);
y=fft(x,N);
mag=abs(y);
f=(0:
N-1)*fs/N; %真实频率
subplot(2,2,4),plot(f(1:
N/2),mag(1:
N/2)*2/N);%绘出Nyquist频率之前的振幅
xlabel('频率/Hz');ylabel('振幅');
title('Ndata=136Nfft=512');gridon;
结论:
(1)当数据个数和FFT采用的数据个数均为32时,频率分辨率较低,但没有由于添零而导致的其他频率成分。
(2)由于在时间域内信号加零,致使振幅谱中出现很多其他成分,这是加零造成的。
其振幅由于加了多个零而明显减小。
(3)FFT程序将数据截断,这时分辨率较高。
(4)也是在数据的末尾补零,但由于含有信号的数据个数足够多,FFT振幅谱也基本不受影响。
对信号进行频谱分析时,数据样本应有足够的长度,一般FFT程序中所用数据点数与原含有信号数据点数相同,这样的频谱图具有较高的质量,可减小因补零或截断而产生的影响。
例3:
x=cos(2*pi*0.24*n)+cos(2*pi*0.26*n)
(1)数据点过少,几乎无法看出有关信号频谱的详细信息;
(2)中间的图是将x(n)补90个零,幅度频谱的数据相当密,称为高密度频谱图。
但从图中很难看出信号的频谱成分。
(3)信号的有效数据很长,可以清楚地看出信号的频率成分,一个是0.24Hz,一个是0.26Hz,称为高分辨率频谱。
可见,采样数据过少,运用FFT变换不能分辨出其中的频率成分。
添加零后可增加频谱中的数据个数,谱的密度增高了,但仍不能分辨其中的频率成分,即谱的分辨率没有提高。
只有数据点数足够多时才能分辨其中的频率成分。
FFT是离散傅立叶变换的快速算法,可以将一个信号变换
到频域。
有些信号在时域上是很难看出什么特征的,但是如
果变换到频域之后,就很容易看出特征了。
这就是很多信号
分析采用FFT变换的原因。
另外,FFT可以将一个信号的频谱
提取出来,这在频谱分析方面也是经常用的。
虽然很多人都知道FFT是什么,可以用来做什么,怎么去
做,但是却不知道FFT之后的结果是什意思、如何决定要使用
多少点来做FFT。
现在圈圈就根据实际经验来说说FFT结果的具体物理意义。
一个模拟信号,经过ADC采样之后,就变成了数字信号。
采样
定理告诉我们,采样频率要大于信号频率的两倍,这些我就
不在此罗嗦了。
采样得到的数字信号,就可以做FFT变换了。
N个采样点,
经过FFT之后,就可以得到N个点的FFT结果。
为了方便进行FFT
运算,通常N取2的整数次方。
假设采样频率为Fs,信号频率F,采样点数为N。
那么FFT
之后结果就是一个为N点的复数。
每一个点就对应着一个频率
点。
这个点的模值,就是该频率值下的幅度特性。
具体跟原始
信号的幅度有什么关系呢?
假设原始信号的峰值为A,那么FFT
的结果的每个点(除了第一个点直流分量之外)的模值就是A
的N/2倍。
而第一个点就是直流分量,它的模值就是直流分量
的N倍。
而每个点的相位呢,就是在该频率下的信号的相位。
第一个点表示直流分量(即0Hz),而最后一个点N的再下一个
点(实际上这个点是不存在的,这里是假设的第N+1个点,也
可以看做是将第一个点分做两半分,另一半移到最后)则表示
采样频率Fs,这中间被N-1个点平均分成N等份,每个点的频率
依次增加。
例如某点n所表示的频率为:
Fn=(n-1)*Fs/N。
由上面的公式可以看出,Fn所能分辨到频率为Fs/N,如果
采样频率Fs为1024Hz,采样点数为1024点,则可以分辨到1Hz。
1024Hz的采样率采样1024点,刚好是1秒,也就是说,采样1秒
时间的信号并做FFT,则结果可以分析到1Hz,如果采样2秒时
间的信号并做FFT,则结果可以分析到0.5Hz。
如果要提高频率
分辨力,则必须增加采样点数,也即采样时间。
频率分辨率和采样时间是倒数关系。
假设FFT之后某点n用复数a+bi表示,那么这个复数的模就是
An=根号a*a+b*b,相位就是Pn=atan2(b,a)。
根据以上的结果,
就可以计算出n点(n≠1,且n<=N/2)对应的信号的表达式为:
An/(N/2)*cos(2*pi*Fn*t+Pn),即2*An/N*cos(2*pi*Fn*t+Pn)。
对于n=1点的信号,是直流分量,幅度即为A1/N。
由于FFT结果的对称性,通常我们只使用前半部分的结果,
即小于采样频率一半的结果。
好了,说了半天,看着公式也晕,下面圈圈以一个实际的
信号来做说明。
假设我们有一个信号,它含有2V的直流分量,频率为50Hz、
相位为-30度、幅度为3V的交流信号,以及一个频率为75Hz、
相位为90度、幅度为1.5V的交流信号。
用数学表达式就是如下:
S=2+3*cos(2*pi*50*t-pi*30/180)+1.5*cos(2*pi*75*t+pi*90/180)
式中cos参数为弧度,所以-30度和90度要分别换算成弧度。
我们以256Hz的采样率对这个信号进行采样,总共采样256点。
按照我们上面的分析,Fn=(n-1)*Fs/N,我们可以知道,每两个
点之间的间距就是1Hz,第n个点的频率就是n-1。
我们的信号
有3个频率:
0Hz、50Hz、75Hz,应该分别在第1个点、第51个点、
第76个点上出现峰值,其它各点应该接近0。
实际情况如何呢?
我们来看看FFT的结果的模值如图所示。
图1FFT结果
从图中我们可以看到,在第1点、第51点、和第76点附近有
比较大的值。
我们分别将这三个点附近的数据拿上来细看:
1点:
512+0i
2点:
-2.6195E-14-1.4162E-13i
3点:
-2.8586E-14-1.1898E-13i
50点:
-6.2076E-13-2.1713E-12i
51点:
332.55-192i
52点:
-1.6707E-12-1.5241E-12i
75点:
-2.2199E-13-1.0076E-12i
76点:
3.4315E-12+192i
77点:
-3.0263E-14+7.5609E-13i
很明显,1点、51点、76点的值都比较大,它附近的点值
都很小,可以认为是0,即在那些频率点上的信号幅度为0。
接着,我们来计算各点的幅度值。
分别计算这三个点的模值,
结果如下:
1点:
512
51点:
384
76点:
192
按照公式,可以计算出直流分量为:
512/N=512/256=2;
50Hz信号的幅度为:
384/(N/2)=384/(256/2)=3;75Hz信号的
幅度为192/(N/2)=192/(256/2)=1.5。
可见,从频谱分析出来
的幅度是正确的。
然后再来计算相位信息。
直流信号没有相位可言,不用管
它。
先计算50Hz信号的相位,atan2(-192,332.55)=-0.5236,
结果是弧度,换算为角度就是180*(-0.5236)/pi=-30.0001。
再
计算75Hz信号的相位,atan2(192,3.4315E-12)=1.5708弧度,
换算成角度就是180*1.5708/pi=90.0002。
可见,相位也是对的。
根据FFT结果以及上面的分析计算,我们就可以写出信号的表达
式了,它就是我们开始提供的信号。
总结:
假设采样频率为Fs,采样点数为N,做FFT之后,某
一点n(n从1开始)表示的频率为:
Fn=(n-1)*Fs/N;该点的模值
除以N/2就是对应该频率下的信号的幅度(对于直流信号是除以
N);该点的相位即是对应该频率下的信号的相位。
相位的计算
可用函数atan2(b,a)计算。
atan2(b,a)是求坐标为(a,b)点的角
度值,范围从-pi到pi。
要精确到xHz,则需要采样长度为1/x秒
的信号,并做FFT。
要提高频率分辨率,就需要增加采样点数,
这在一些实际的应用中是不现实的,需要在较短的时间内完成
分析。
解决这个问题的方法有频率细分法,比较简单的方法是
采样比较短时间的信号,然后在后面补充一定数量的0,使其长度
达到需要的点数,再做FFT,这在一定程度上能够提高频率分辨力。
具体的频率细分法可参考相关文献。
[附录:
本测试数据使用的matlab程序]
closeall;%先关闭所有图片
Adc=2;%直流分量幅度
A1=3;%频率F1信号的幅度
A2=1.5;%频率F2信号的幅度
F1=50;%信号1频率(Hz)
F2=75;%信号2频率(Hz)
Fs=256;%采样频率(Hz)
P1=-30;%信号1相位(度)
P2=90;%信号2相位(度)
N=256;%采样点数
t=[0:
1/Fs:
N/Fs];%采样时刻
%信号
S=Adc+A1*cos(2*pi*F1*t+pi*P1/180)+A2*cos(2*pi*F2*t+pi*P2/180);
%显示原始信号
plot(S);
title('原始信号');
figure;
Y=fft(S,N);%做FFT变换
Ayy=(abs(Y));%取模
plot(Ayy(1:
N));%显示原始的FFT模值结果
title('FFT模值');
figure;
Ayy=Ayy/(N/2);%换算成实际的幅度
Ayy
(1)=Ayy
(1)/2;
F=([1:
N]-1)*Fs/N;%换算成实际的频率值
plot(F(1:
N/2),Ayy(1:
N/2));%显示换算后的FFT模值结果
title('幅度-频率曲线图');
figure;
Pyy=[1:
N/2];
fori="1:
N/2"
Pyy(i)=phase(Y(i));%计算相位
Pyy(i)=Pyy(i)*180/pi;%换算为角度
end;
plot(F(1:
N/2),Pyy(1:
N/2));%显示相位图
title('相位-频率曲线图');
看完这个你就明白谐波分析了。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MATLAB FFT 使用方法
![提示](https://static.bdocx.com/images/bang_tan.gif)