求用C语言实现FFT变换的程序(见下面)

供稿:hz-xin.com     日期:2025-01-15
求用matlab或者C语言实现的FFT变换程序

你好,这是我的回答,希望可以帮到你。

1)结果讨论

一,如果对信号进行同样点数N的FFT变换,采样频率fs越高,则可以分析越高频的信号;与此同时,采样频率越低,对于低频信号的频谱分辨率则越好。

二,假设采样点不在正弦信号的波峰、波谷、以及0电压处,频谱则会产生泄露(leakage)。

三,对于同样的采样率fs,提高FFT的点数N,则可提高频谱的分辨率。

四,如果采样频率fs小于2倍信号频率2*fs(奈圭斯特定理),则频谱分析结果会出错。

五,对于(二)中泄露现象,可以通过在信号后面补零点解决。


2)程序及注解如下

%清除命令窗口及变量
clc;
clear all;

%输入f、N、T、是否补零(补几个零)
f=input('Input frequency of the signal: f
');
N=input('Input number of pointsl: N
');
T=input('Input sampling time: T
');
flag=input('Add zero too sampling signal or not? yes=1 no=0
');
if(flag)
ZeroNum=input('Input nmber of zeros
');
else
ZeroNum=0;
end

%生成信号,signal是原信号。signal为采样信号。
fs=1/T;
t=0:0.00001:T*(N+ZeroNum-1);
signal=sin(2*pi*f*t);
t2=0:T:T*(N+ZeroNum-1);
signal2=sin(2*pi*f*t2);
if (flag)
signal2=[signal2 zeros(1, ZeroNum)];
end

%画出原信号及采样信号。
figure;
subplot(2,1,1);
plot(t,signal);
xlabel('Time(s)');
ylabel('Amplitude(volt)');
title('Singnal');
hold on;
subplot(2,1,1);
stem(t2,signal2,'r');
axis([0 T*(N+ZeroNum) -1 1]);


%作FFT变换,计算其幅值,归一化处理,并画出频谱。
Y = fft(signal2,N);
Pyy = Y.* conj(Y) ;
Pyy=(Pyy/sum(Pyy))*2;
f=0:fs/(N-1):fs/2;4
subplot(2,1,2);
bar(f,Pyy(1:N/2));
xlabel('Frequency(Hz)');
ylabel('Amplitude');
title('Frequency compnents of signal');
axis([0 fs/2 0 ceil(max(Pyy))])
grid on;

祝你好运!

我也写了个fft程序,256点时计算还正确,但是512和1024点结果就错了,希望楼主答案的话能告知,

你好,这是我的回答,希望可以帮到你。

1)结果讨论

一,如果对信号进行同样点数N的FFT变换,采样频率fs越高,则可以分析越高频的信号;与此同时,采样频率越低,对于低频信号的频谱分辨率则越好。

二,假设采样点不在正弦信号的波峰、波谷、以及0电压处,频谱则会产生泄露(leakage)。

三,对于同样的采样率fs,提高FFT的点数N,则可提高频谱的分辨率。

四,如果采样频率fs小于2倍信号频率2*fs(奈圭斯特定理),则频谱分析结果会出错。

五,对于(二)中泄露现象,可以通过在信号后面补零点解决。

2)程序及注解如下

%清除命令窗口及变量
clc;
clear all;

%输入f、N、T、是否补零(补几个零)
f=input('Input frequency of the signal: f\n');
N=input('Input number of pointsl: N\n');
T=input('Input sampling time: T\n');
flag=input('Add zero too sampling signal or not? yes=1 no=0\n');
if(flag)
ZeroNum=input('Input nmber of zeros\n');
else
ZeroNum=0;
end

%生成信号,signal是原信号。signal为采样信号。
fs=1/T;
t=0:0.00001:T*(N+ZeroNum-1);
signal=sin(2*pi*f*t);
t2=0:T:T*(N+ZeroNum-1);
signal2=sin(2*pi*f*t2);
if (flag)
signal2=[signal2 zeros(1, ZeroNum)];
end

%画出原信号及采样信号。
figure;
subplot(2,1,1);
plot(t,signal);
xlabel('Time(s)');
ylabel('Amplitude(volt)');
title('Singnal');
hold on;
subplot(2,1,1);
stem(t2,signal2,'r');
axis([0 T*(N+ZeroNum) -1 1]);

%作FFT变换,计算其幅值,归一化处理,并画出频谱。
Y = fft(signal2,N);
Pyy = Y.* conj(Y) ;
Pyy=(Pyy/sum(Pyy))*2;
f=0:fs/(N-1):fs/2;4
subplot(2,1,2);
bar(f,Pyy(1:N/2));
xlabel('Frequency(Hz)');
ylabel('Amplitude');
title('Frequency compnents of signal');
axis([0 fs/2 0 ceil(max(Pyy))])
grid on;

祝你好运!
我可以帮助你,你先设置我最佳答案后,我百度Hii教你。

这是一个傅里叶变化的子函数,你可以自己做主函数传递你这里的参数验证
// 入口参数:
// l: l = 0, 傅立叶变换; l = 1, 逆傅立叶变换
// il: il = 0,不计算傅立叶变换或逆变换模和幅角;il = 1,计算模和幅角
// n: 输入的点数,为偶数,一般为32,64,128,...,1024等
// k: 满足n=2^k(k>0),实质上k是n个采样数据可以分解为偶次幂和奇次幂的次数
// pr[]: l=0时,存放N点采样数据的实部
// l=1时, 存放傅立叶变换的N个实部
// pi[]: l=0时,存放N点采样数据的虚部
// l=1时, 存放傅立叶变换的N个虚部
//
// 出口参数:
// fr[]: l=0, 返回傅立叶变换的实部
// l=1, 返回逆傅立叶变换的实部
// fi[]: l=0, 返回傅立叶变换的虚部
// l=1, 返回逆傅立叶变换的虚部
// pr[]: il = 1,l = 0 时,返回傅立叶变换的模
// il = 1,l = 1 时,返回逆傅立叶变换的模
// pi[]: il = 1,l = 0 时,返回傅立叶变换的辐角
// il = 1,l = 1 时,返回逆傅立叶变换的辐角

void kbfft(double *pr,double *pi,int n,int k,double *fr,double *fi,int l,int il)
{
int it,m,is,i,j,nv,l0;
double p,q,s,vr,vi,poddr,poddi;

//排序
for (it=0; it<=n-1; it++)
{ m=it; is=0;
for (i=0; i<=k-1; i++)
{ j=m/2; is=2*is+(m-2*j); m=j;
fr[it]=pr[is]; fi[it]=pi[is];
}
}

//蝶形运算
pr[0]=1.0; pi[0]=0.0;
p=6.283185306/(1.0*n);
pr[1]=cos(p); pi[1]=-sin(p);
if (l!=0) pi[1]=-pi[1];
for (i=2; i<=n-1; i++)
{ p=pr[i-1]*pr[1]; q=pi[i-1]*pi[1];
s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);
pr[i]=p-q; pi[i]=s-p-q;
}
for (it=0; it<=n-2; it=it+2)
{ vr=fr[it]; vi=fi[it];
fr[it]=vr+fr[it+1]; fi[it]=vi+fi[it+1];
fr[it+1]=vr-fr[it+1]; fi[it+1]=vi-fi[it+1];
}
m=n/2; nv=2;
for (l0=k-2; l0>=0; l0--)
{ m=m/2; nv=2*nv;
for (it=0; it<=(m-1)*nv; it=it+nv)
for (j=0; j<=(nv/2)-1; j++)
{ p=pr[m*j]*fr[it+j+nv/2];
q=pi[m*j]*fi[it+j+nv/2];
s=pr[m*j]+pi[m*j];
s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]);
poddr=p-q; poddi=s-p-q;
fr[it+j+nv/2]=fr[it+j]-poddr;
fi[it+j+nv/2]=fi[it+j]-poddi;
fr[it+j]=fr[it+j]+poddr;
fi[it+j]=fi[it+j]+poddi;
}
}
if (l!=0)
for (i=0; i<=n-1; i++)
{ fr[i]=fr[i]/(1.0*n);
fi[i]=fi[i]/(1.0*n);
}
if (il!=0)
for (i=0; i<=n-1; i++)
{ pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]);
pr[i]=(pr[i]/(n/2)); //各次谐波幅值,其中pr[1]为基波幅值
if (fabs(fr[i])<0.000001*fabs(fi[i]))//fabs()是取绝对值函数,浮点型的0 在内存中并不是严格等于0,可以认为当一个浮点数

离原点足够近时,也就是f>0.00001 && f<-0.00001,认为f是0
{ if ((fi[i]*fr[i])>0) pi[i]=90.0;
else pi[i]=-90.0;
}
else
pi[i]=atan(fi[i]/fr[i])*360.0/6.283185306;
}
return;
}

基于FFT的算法优化 要C语言完整程序(利用旋转因子的性质),有的请留言...
2011-12-05 怎样用C语言实现FFT算法啊? 3 2016-07-18 在静态fft实验中,程序所计算的fft图像有什么特点 2011-07-19 急急急!!!求FFT优化后的算法C语言代码!!大哥大姐帮帮忙... 2013-05-19 关于旋转因子 19 2015-01-09 谁能给一个C语言的FFT算法程序啊,急用 2015-07-23 求基2、基4、基8FFT...

跪求大师用C语言帮我编一个8点基-2按时间抽取的FFT程序
用递归应该比较容易写的, 虽然效率差一些 大概思路:用一个函数做准备:把数组排列成到位序 计算Wn 对整个数组调用 do_fft函数 do_fft函数:如果需要计算的序列长为2,两个位置分别写为x[0]+x[1]和x[0]-x[1]然后返回 对需要计算的序列前半部分调用do_fft函数 对需要计算的序列后半副本调用do...

离散傅里叶变换在C语言中得写法
axes2); % 设置图像显示轴 imshow(A); % 显示图像 快速离散二维傅里叶变换 I=imread('Miss.bmp');figure(1)[m,n]=size(I)for k=1:n wht(:,k)=hadmard(m)*I(:,k)\/m;end %沃尔什变换 以上在matlab实现

求基2、基4、基8FFT(快速傅里叶变换)的c语言程序,要能运行得出来的
1.FFT:\/\/ data为输入和输出的数据,N为长度bool CFFT::Forward(complex *const Data, const unsigned int N){ if (!Data || N < 1 || N & (N - 1)) return false; \/\/ 排序 Rearrange(Data, N); \/\/ FFT计算:const bool Inverse = false Perform(Data,...

用C语言编写快速傅立叶变换源代码
\/\/ 函数名: 快速傅立叶变换(来源《C常用算法集》)\/\/ 本函数测试OK,可以在TC2.0,VC++6.0,Keil C51测试通过。\/\/ 如果你的MCS51系统有足够的RAM时,可以验证一下用单片机处理FFT有多么的慢。\/\/ \/\/ 入口参数:\/\/ l: l = 0, 傅立叶变换; l = 1, 逆傅立叶变换 \/\/ il: il = 0,...

1周学FFT——第7天 Cooley-Tukey算法的C语言实现
作为递归算法,Cooley-Tukey由数学天才高斯在160年前发明,后经Cooley和Tukey在不同背景独立发现。算法核心在于时间抽选奇偶分解基-2FFT,以下是其伪代码和C语言实现。伪代码示例:实现细节包含定义复数数据结构MyComplex、复数运算函数以及主程序的时间抽选奇偶分解基-2 FFT算法。实现后,通过调用函数和测试,...

C语言编程问题出现错误Cannot open include file: 'stdafx.h': No s...
C语言编程问题出现错误Cannot open include file: 'stdafx.h': No such file or directory大家帮帮忙吧 10 #include"stdafx.h"#include<stdio.h>#include<math.h>#include<stdlib.h>#include<graphics.h>#include<conio.h>#defineN1000\/*定义复数类型*\/typedefstruct{doublereal;doubleimg;}... #include "...

求助fft.lib 做的IFFT变换的程序
temp++) { ipcb[temp*2+1]=-ipcb[temp*2+1]; \/\/求共轭复根 } \/***再求FFT变换***\/ CFFT32_brev2(ipcb,ipcb,FFT_N); fft.izero(&fft); fft.calc(&fft); \/***\/ for(temp=0;temp<FFT_N;temp++) { \/*再求共轭复根再 其实已经没有虚部了 \/N*\/ ipcb[temp*2]=((ipcb...

有谁用C语言实现过correl函数
很经典的 Numerical Recipes in C 里有。网上可以查到。网页链接 例子:void correl(data1,data2,n,ans)float data1[],data2[],ans[];int n;{int no2,i;float dum,*fft,*vector();void twofft(),realft(),free_vector();fft=vector(1,2*n);twofft(data1,data2,fft,ans,n);no...

c语言问题,求高手编写一个程序 编写程序: (1)求一个字符串S1的长度...
\/ 串s = ads 串t = fftgds s -> d,d = ads d + t = adsfftgds len of d = 9 请按任意键继续. . .\/ include <stdio.h> int strlen(char *s) { int i,len = 0;for(i = 0; s[i]; ++i) ++len;return len;} char *strcpy(char s2[], char s1[]) { int i;fo...