前些时间折腾了一下FFT,是从用AD来采集50HZ的信号来实验的折腾了很久感觉方法是对的,但数据又偏得有点点大。在网上发了两个贴子,都没人理,不知是这个问题太小儿科了,还是在网上大谈理论的人太多了,实用时就不知道了,还是这个技术很来钱,别人不愿意交会其他人。呵呵,反正是没在网上得到一句答案。无赖之下,只有自己动手了解。
两年前在网上找了一个基2的FFT程序,我又自己把它修改了并重新封装了一下,昨天不小心,把这个代码找了出来。并基于公司新开发的ARM板子来做了个64点的仿真的实验。
实验代码如下:
Complex SinTab[64],VialCode1[64]; //我自己定义的一个复数据的数据结构,在FFT.H中
float SineValue[64],PIdot;
short VialCode[64];
PIdot = PI2/8; // 确定一个周期内产生8个点的数据
initW(SinTab,64); //产生FFT用的正弦表,为64点FFT做准备
for(i1=0;i1<64;i1++) //产生正弦信号数据
{
SineValue[i1] = 2.5+0.283*cos(PIdot*(i1%8)); //使用函数生成一个周期8个采集点的数据,模拟AD端口电压
VialCode[i1] = SineValue[i1]/0.00122;//假设AD的分辨率为1.22mV,通过这里模拟AD采集到的编码数据
}
for(i1=0;i1<64;i1++) //将模拟的AD编码数据组装为复数
{
VialCode1[i1].real=VialCode[i1];
VialCode1[i1].img=0;
}
fft(VialCode1,64,SinTab,1);//FFT运算,在FFT.H中定义的
for(i1=0;i1<64;i1++)//将FFT后的数据进行取模,即实部的平方+虚部的平方后再开方
{
VialCode[i1]=sqrt( VialCode1[i1].real*VialCode1[i1].real + VialCode1[i1].img*VialCode1[i1].img );
}
通过函数得到的数据如下所示:

模拟成AD采集到的编码数据波形如下:

FFT变换以后取模的数据波形如下:

上图中第一个数据是:120640 那两个小尖尖的数据是(第8点):7422(因为是对称的),程序中,每周期虚拟8个采集点,一共使用64个点来运算,如按上述的AD分辨率=1.22mV来计算:
0点直流:120640/64=1885 直流幅值=1885*1.22=2.299V
8点交流:7422/(64/2)=232.56 交流幅值=232.56*1.22=0.284V
如AD采集频率为400HZ,则频率的分辩率为:400/64=6.25HZ。如果要看50Hz的信号,则50/6.25=8,即交流分量的第八个点上。
与输入波形的值一至。所以这就是FFT的完整应用流程了。
我整理过的基二FFT源码:
FFT.Cpp.rar
FFT.h.rar
欢迎各位指教与交流。
mail:zxw36792116@hotmail.com
www.uectr.com
谢谢!