This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
学习的例程,使用蝶形运算进行fft。
发现改变NL(即N)从256变成512,fft结果变差,output[5]从0.99变成0.95
而且相位值利用fft输出Sample[N]数组计算 atan2(Sample[5].imag,Sample[5].real)和产生的输入数据不符合,这是为什么呢?fft计算方法有错误么?
附件是fft主函数,cmd文件就在N变成512时增大了DRAMH0 ,长度从0x001000变成0x002000
#include "DSP281x_Device.h" // DSP281x Headerfile Include File #include "DSP281x_Examples.h" // DSP281x Examples Include File #include <math.h> #define pi 3.141593 // floatС�����6λ #define NL 256 // NLΪ�ϳ��źŵ�������N��ֵ������һ�µģ���NL=N int N=NL; //FFT���� float Input[NL];//������ź����� /* float h[33] = { 0.000744808099883,0.0008898861356028,-0.002727390076489, 0.002920995444386, 0.0009645511494193,-0.008002287495031, 0.01133584612049,-0.002751488761016, -0.01688113961025, 0.0316509088309, -0.01948352023097, -0.02634617068536, 0.07974565309008, -0.08470853564896, -0.03245044438095, 0.5650983280183, 0.5650983280183, -0.03245044438095, -0.08470853564896, 0.07974565309008, -0.02634617068536, -0.01948352023097, 0.0316509088309, -0.01688113961025, -0.002751488761016, 0.01133584612049,-0.008002287495031,0.0009645511494193, 0.002920995444386,-0.002727390076489,0.0008898861356028, 0.000744808099883 }; float h[32]= { 0 , -0.00009 , 0.00042 , 0.00108 , -0.00224 , -0.00413 , 0.00704 , 0.01135, -0.01756 , -0.02634 , 0.03871 , 0.05650 , -0.08349 , -0.12957 , 0.23113 , 0.71720, 0.71720 , 0.23113 , -0.12957 , -0.08349 , 0.05650 , 0.03871 , -0.02634 , -0.01756, 0.01135 , 0.00704 , -0.00413 , -0.00224 , 0.00108 , 0.00042 , -0.00009 , 0 }; */ //Uint16 SampleTable[NL]; struct Complex // ���帴���ṹ�� { float real,imag; }; struct Complex Wn;//������ת���� struct Complex Vn;//ÿһ����һ����ת�����鲿Ϊ0��ʵ��Ϊ1 struct Complex T;//�����ת������X(k+B)�ij˻� //float Realin[NL]={0};// ���������ʵ�� float output[NL]={0};// �����FFT��ֵ��������ģ�� struct Complex Sample[NL];// ���������ʵ��ת��Ϊ���� struct Complex MUL(struct Complex a,struct Complex b)//���帴�� { struct Complex c; c.real=a.real*b.real-a.imag*b.imag; c.imag=a.real*b.imag+a.imag*b.real; return(c); } void MYFFT(struct Complex *xin,int N)//����Ϊ����ָ��*xin����N��FFT { int L=0; // ��������� int J=0; // ��������� int K=0,KB=0; // ��������� int M=1,Nn=0;// N=2^M float B=0; // �����������������ݼ�� /* ������Ϊ�����½��ľֲ�����*/ int LH=0,J2=0,N1=0,I,K2=0; struct Complex T; /*�����ǵ���*/ LH=N/2; // LH=N/2 J2=LH; N1=N-2; for(I=1;I<=N1;I++) { if(I<J2) { T=xin[I]; xin[I]=xin[J2]; xin[J2]=T; } K2=LH; while(J2>=K2) { J2-=K2; K2=K2/2;// K2=K2/2 } J2+=K2; } /* ����Ϊ�����M */ Nn=N; while(Nn!=2)// �����N����2Ϊ��������M { M++; Nn=Nn/2; } /* �������� */ for(L=1;L<=M;L++) // ���� { B=pow(2,(L-1)); Vn.real=1; Vn.imag=0; Wn.real=cos(pi/B); Wn.imag=-sin(pi/B); for(J=0;J<B;J++) // ���� { for(K=J;K<N;K+=2*B) // ������������ { KB=K+B; T=MUL(xin[KB],Vn); xin[KB].real=xin[K].real-T.real;//ԭַ���㣬�����������ԭ���������� xin[KB].imag=xin[K].imag-T.imag; xin[K].real=xin[K].real+T.real; xin[K].imag=xin[K].imag+T.imag; } Vn=MUL(Wn,Vn);// ��ת�����������൱��ָ����ӣ��õ��Ľ�� // ��J*2^��M-L����һ���ģ���Ϊ�ڵ����������� // ����M��L���Dz���ģ�Ψһ��x�����Ǽ��ڵ�J // ����J����1Ϊ�����ģ���J*W��Ч��W+W+W...J��W��� } } } /* void FilterDC(struct Complex *ADC,int N)//ȥ�������е�ֱ���ɷ֣�����ֱ���������ܴ� { int i; float sum=0; for(i=0;i<N;i++) { sum+=ADC[i].real;} sum=sum/N; for(i=0;i<N;i++) { ADC[i].real-=sum;} }*/ /******************************** ���ܣ����㸴����ģ �βΣ�*Sampleָ����Ҫȡģ�ĸ����ṹ�� NΪȡģ���� *output���ȡģ����ֵ������ *********************************/ void ModelComplex(struct Complex *Sample,int N,float *output) { int i; for(i=0;i<N;i++) { output[i]=sqrt(Sample[i].real*Sample[i].real+Sample[i].imag*Sample[i].imag)*2/N; } } void main(void) { Uint16 i=0; InitSysCtrl(); // InitXintf16Gpio(); // InitAdc(); DINT; InitPieCtrl(); IER = 0x0000; IFR = 0x0000; for(i=0;i<NL;i++) //����һ������г�����Ӷ��ɵķ��� { Input[i]=sin(2*pi*5*i/(NL-1))+sin(2*pi*i*5*3/(NL-1))/3+sin(2*pi*i*5*5/(NL-1))/5; } for(i=0;i<NL;i++) //����ʵ���ź�ת��Ϊ���� { Sample[i].real=Input[i]; // Sample[i].real=h[i]; Sample[i].imag=0; } MYFFT(Sample,NL); //FFT ModelComplex(Sample,NL,output); //��ģ while(1) { // FilterDC(Sample,NL); } } //=========================================================================== // No more. //===========================================================================
您好,谢谢你的回复。输入信号采用的 Input[i]=sin(2*pi*5*i/(NL-1)+30*pi/180)+sin(2*pi*i*5*3/(NL-1)+60*pi/180)/3+sin(2*pi*i*5*5/(NL-1)+90*pi/180)/5;
N改变后,对应的基波应该还是在output[5]这个位置呀。而且output中最大值一直就是在5hz这个频率点,从0.99变成了0.95.
相位用虚部实部计算就不是输入信号。
我用matlab进行fft,对同样的信号进行变换,fft输出结果的虚实部满足输入信号的幅值和相位,是这种fft算法不对么? dsp实现fft的结果和matlab实现fft的结果不一样,虚部实部不同
没用ti的库,用的研旭的例程,我试了N变成128,输出的output[5]也十分接近1,N=256就是例程自带的。N=512就变差了,这个Fs采样频率,我看程序中好像没有定义,针对的信号是相同的,N不同,采样点数值也会变化。我直接查看fft计算结果,发现输出复数的虚部实部和matlab计算的并不相同
TI库的fft函数实在看不懂cfft32xxx.asm的内容,同时也不明白fft.ipcbptr ,fft.magptr之类的代表什么,我没找到这个fft包含的东西,您那有TI库的使用例子么?
void MYFFT(struct Complex *xin,int N)//输入为复数指针*xin,做N点的FFT
{
int L=0;//级间运算层
int J=0;//级内运算层
int K=0,KB=0;//蝶形运算层
int M=1,Nn=0;//N=2^M
float B=0;//蝶形运算亮数据间隔
//建立倒序运算局部变量
int LH=0,J2=0,N1=0,K2=0,I;
struct Complex T;
//倒序运算
LH=N/2;
J2=LH;
N1=N-2;
for(I=1;I<=N1;I++) //N1有问题
{
if(I<J2)
{
T=xin[I];
xin[I]=xin[J2];
xin[J2]=T;
}
K2=LH;
while(J2>=K2)
{
J2-=K2;
K2=K2/2;
}
J2+=K2;
}
//计算M
Nn=N;
while(Nn!=2)
{
M++;
Nn=Nn/2;
}
//蝶形运算
for(L=1;L<=M;L++)
{
B=pow(2,(L-1));
Vn.real=1;
Vn.imag=0;
Wn.real=cos(pi/B);
Wn.imag=-sin(pi/B); //Wn=cos(pi/2^(L-1))-j*sin(pi/2^(L-1))
//Wn=e^(-j*2pi/2^L)
for(J=0;J<B;J++)//级内
{
for(K=J;K<N;K=K+2*B)//蝶形
{
KB=K+B;
T=MUL(xin[KB],Vn);
xin[KB].real=xin[K].real-T.real;//原址运算,将计算结果存放在原来数组中
xin[KB].imag=xin[K].imag-T.imag;
xin[K].real=xin[K].real+T.real;
xin[K].imag=xin[K].imag+T.imag;
}
Vn=MUL(Wn,Vn);
}
}
}
for(i=0;i<NL;i++) //产生一个三次谐波叠加而成的方波
{
//Input[i]=sin(2*pi*5*i/(NL-1));
Input[i]=sin(2*pi*5*i/(NL-1))+sin(2*pi*i*5*3/(NL-1)+pi*30/180)/3+sin(2*pi*i*5*5/(NL-1)+pi*90/180)/5;
//Input[i]=2+3*cos(2*pi*50*i/(NL-1)-pi*30/180)+1.5*cos(2*pi*75*i/(NL-1)+pi*90/180);
}
for(i=0;i<NL;i++) //输入实数信号转换为复数
{
Sample[i].real=Input[i];
Sample[i].imag=0;
}
MYFFT(Sample,NL); //FFT
ModelComplex(Sample,NL,output); //求模
PhaseComplex(Sample,NL,phase);
N变化,由于使用的是 Input[i]=sin(2*pi*5*i/(NL-1)+30*pi/180)+sin(2*pi*i*5*3/(NL-1)+60*pi/180)/3+sin(2*pi*i*5*5/(NL-1)+90*pi/180)/5;这种作为输入采样数据,可见其采样频率也跟着变化了呀
Fn=(n-1)*Fs/N对应的频率点应该仍旧是n Hz吧,相当于是256采样点,采样频率256Hz;512采样点,采样频率512Hz
之前没注意到你的这个信号源,这样的话,的确信号源频率有跟着变化,对应的点虽然频率不是原来的频率,但是却是原来的幅值。
理想情况是一致的,但由于fft的本身一些效应,结果会有一些差异。
FFT算法是一致的,用汇编实现是针对dsp的优化,完全可以不用管。