|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2011-1-24 16:24:28
|
显示全部楼层
上程序
======================
#include<math.h>//要调入数学(和谐)运算的头文件
#include<reg52.h>
//定义复数结构
struct compx
{
float real;
float imag;
};
//定义复数乘法
struct compx EE(struct compx a,struct compx b)
{
struct compx c;
c.real=a.real*b.real-a.imag*b.imag;
c.imag=a.real*b.imag+a.imag*b.real;
return(c);
}
//定义复数求模
float cmplxabs(struct compx a)
{
float b;
b=sqrt(a.real*a.real+a.imag*a.imag);
return(b);
}
//FFT子程序
//入口:复数数组指针和点数。
//出口:原复数数组,取模后为强度,可用于频谱。
void FFT(struct compx *xin,unsigned int N)
{
int f,m,nv2,nm1,i,k,j=1,l;
int le,lei,ip;
struct compx v,w,t;
nv2=N/2;
f=N;
for(m=1;(f=f/2)!=1;m++);
nm1=N-1;
for(i=1;i<=nm1;i++){
if(i<j){t=xin[j-1];xin[j-1]=xin[i-1];xin[i-1]=t;}
k=nv2;
while(k<j){j=j-k;k=k/2;}
j=j+k;
}
/* FFT*/
for(l=1;l<m;l++)
{
le=pow(2,l);
lei=le/2;
v.real=1.0;v.imag=0.0;
w.real=cos(pi/lei);w.imag=-sin(pi/lei);
for(j=1;j<=lei;j++){
for(i=j;i<=N;i+=le){
ip=i+lei;
t=EE(xin[ip-1],v);
xin[ip-1].real=xin[i-1].real-t.real;
xin[ip-1].imag=xin[i-1].imag-t.imag;
xin[i-1].real=xin[i-1].real+t.real;
xin[i-1].imag=xin[i-1].imag+t.imag;
}
v=EE(v,w);
}
}
}
//使用示例
xdata struct compx s[128];//我的有1024字节外部RAM,可做128点FFT。
void main()
{
unsigned char i,bar[64];
for(;;){
for(i=0;i<=127;i++){
……………………//AD采样
s.real=(float)ADC_RES;//采样结果送实部,注意数据类型转换
s.imag=0;
}
FFT(s,128);
//由于FFT的结果是关于中间对称的,只需要左半边结果
for(i=0;i<=63;i++)bar=(unsigned char)(complxabs(s)/50);//需要除一个数,免得结果太大转换出错。具体多少需调试。
……………………//显示转换结果
}
} |
|