FFT在嵌入式系统上的成功运用
-
最近关于FFT方面的东西,研究了好多,有很多感触:一方面对自己工作的总结;一方面和大家一起分享一下希望对大家会有一点帮助。
FFT基本原理
FFT,全称为快速傅里叶变换,目的是把时域的信号转变为频域的信号,FFT的作用就是通过计算,把信号的各个频率成分找出来, 借用凹凸曼的大表哥的一张图:
怎么计算昵?
子曰:“工欲善其事,必先利其器。我们先来看看大名鼎鼎的mathlab如何做的:
先生成一个复合信号:
该信号由直流信号,50hz余弦波和833hz的正弦波构成,代码如下:
Adc=50; %直流分量幅度
A1=220; %频率F1信号的幅度
F1=50; %信号1频率(Hz)
P1=-30; %信号1相位(度)
A2=30; %频率F2信号的幅度
F2=833;%833;%75; %信号2频率(Hz)
P2=90; %信号相位(度)
Fs=6400;%采样频率(Hz)
N=1024;%采样点数
t=[0:1/Fs:N/Fs]; %采样时刻
%信号
S=Adc+A1cos(2piF1t+piP1/180)+A2cos(2piF2t+piP2/180);
经过mathlab合成后,plot(S);%显示原始信号,输出波形:
对复合信号进行FFT:
Y = fft(S,N); %做FFT变换
FFT之后得到的那一串复数是波形对应频率下的幅度特征,结果并不直接对应信号包含的频率成分,绝大部分的FFT算法计算出来后都需要进行幅度的转换的,FFT的结果的第一个点对应直流分量,它的模值就是直流分量的N倍,要得出真实幅值,需要把除了第1个点(i=0)以及最后一个点(i=N/2)除以N以外,其余点把求得的模除以N/2 ,把各个点的模值显示出来就是:可以看出,FFT结果的对称性,通常我们只使用前半部分的结果,
即小于采样频率一半的结果。
如何才能分辨出信号包含的频率成分昵?这就需要另一个关键参数:分辨率,要理解分辨率,首先要从大名鼎鼎的"奈奎斯特定理"。说起, 这个定理的意思是,如要采集到完整的原始模拟信号,对其采样的频率必须大于该原始模拟信号频率2倍及以上。当然倍数越高得到的结果越接近原始值,例如我们用到的频率50hz和833HZ的信号,理论上模拟芯片采样频率至少要达到1666HZ。实际应用中不会这么做,因为1666HZ太低了,如果要通过FFT运算得到尽可能准确的结果,就要尽量的提高采样率,就像我们采用的是6400Hz,知道了这个原理,分辨率就好理解了:
分辨率=采样频率÷采样样本数的值
此处:分辨率=6400/1024=6.25hz
可以看出,要想提高fft的分辨率(越小越好),则必须增加采样点数,也即采样时间。频率分辨率和采样时间是倒数关系。
如何才能找出信号包含的频率分量和对应的幅值昵?
代码如下:
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模值结果
至此,我们已经清晰看到了信号的频点分布