深入浅出解释FFT(四)——fft分析信号频率和相位

很基础的问题往往很重要,做仿真时候有一个点的差错都会导致结果的错误。在网上找了前人写的东东,总结下希望对大家有帮助,让大家少走一些弯路。

  1. 信号的时域采样点N和频域采样点数相同

%##################################################################

clear all; close all;
Adc =1.25; %直流分量幅度
A1 =1; %频率F1信号的幅度
A2 =0.25; %频率F2信号的幅度
F1 =100; %信号1频率(Hz)
F2 =1000; %信号2频率(Hz)
Fs =5120; %采样频率(Hz)

Ts =1/Fs; %时域采样间隔,采样周期
P1 =-30; %信号1相位(度)
P2 =90; %信号2相位(度)
N =256; %采样点数,请注意时域采样N点,FFT时也是N点!
t = [0 : 1/Fs : N/Fs]; %采样时刻,注意不是序列是真正的时间!t = [0:N]*Ts

% t = [0 : N]//Fs; %共采样257个点,为了好看起见多采样了最后一个点,最后一个点在实际中应该是下一个采样周期的第一个点

%生成信号
%S=Adc+A1cos(2piF1t+piP1/180)+A2cos(2piF2t+piP2/180); %考虑相位
signal1=A1sin(2piF1t); % 周期T1 = 2pi/(2pi*F1) = 0.01s,采样周期Ts = 0.00019531 < (T1)/2

signal2=A2sin(2piF2t); % 周期T2 = 2pi/(2piF2) = 0.001s,采样周期Ts = 0.00019531 < (T2)/2
S=A1
sin(2piF1t)+A2sin(2piF2t); %无直流偏置
S=Adc+A1
sin(2piF1t)+A2sin(2piF2t); %直流偏置
%S=Adc+[A1
sin(2piF1t)+A2sin(2piF2*t)]/2;

S=Adc+A1cos(2piF1t+piP1/180)+A2cos(2piF2t+piP2/180);%考虑相位
%显示原始信号
plot(S);
title(‘原始信号’);

figure;
Y = fft(S,N); %做FFT变换
Ayy = (abs(Y)); %取模
plot(Ayy(1:N)); %显示原始的FFT模值结果
title(‘FFT 模值’);

F = ([1:N] - 1) * Fs /N; %换算成实际的频率值, N*Fs/2 对应着w = pi
% 因为MATLAB中FFT的变换矩阵不是一个酉矩阵(Unitary Matrix),该阵除以1/sqrt(N)就是个酉矩阵。故经过变换后对信号有放大作用,

% 所以要在fft处理后结果除以N/2来,修正此“放大”作用。但是结果在直流的那一点是错误的,实际上直流应该除以N修正。

Ytemp = 2/N * fft(S,N); % 做FFT变换后除以N/2修正

figure; plot(F, abs(Ytemp));title(‘实际幅度-频率曲线图 — abs前修正’);

figure;
Ayy = Ayy / (N /2); %换算成实际的幅度
Ayy(1) = Ayy(1) /2; %能看出来为什么直流信号除以N了吗?我开始没看出来啊

%假设采样频率为Fs,采样点数为N,做FFT之后,某一点n(n从1开始)表示的频率为:Fn=(n-1)*Fs/N;该点的模值除以N/2就是对应

%该频率下的信号的幅度(对于直流信号是除以N)

根据公式验证 — 某点n所表示的频率为: Fn=(n-1)*Fs/N,因为没有fftshift

                                f1=(6-1)*5120/256=100 (Hz) ---- 验证结果正确

                                f2=(51-1)*5120/256=1000(Hz)---- 验证结果正确

根据公式验证 — 对于n=1点的信号,是直流分量,幅度即为A1/N — A1=320/256=1.25 — 验证结果正确

对于n点(n≠1,且n<=N/2) 幅度A — A=An/(N/2)=128/(256/2)=1 — 验证结果正确

plot(F(1:N/2),Ayy(1:N/2)); %显示换算后的FFT模值结果,只看0~N*Fs/2正频谱部分
title(‘实际幅度-频率曲线图 — abs后修正’);

figure;

% 相位的计算可用函数atan2(b,a)计算。atan2(b,a)是求坐标为(a,b)点的角度值,范围从-pi到pi。

% atan2(500, 148)=x,结果是弧度,换算为角度就是180*(-x)/pi=相位值。

Pyy = [1 : N/2];
for i = 1 : N/2
Pyy(i) =phase(Y(i)); %计算相位
Pyy(i) = Pyy(i) * 180 /pi; %换算为角度
end;
plot(F(1 : N/2), Pyy(1 : N/2)); %显示相位图
title(‘相位-频率曲线图’);

根据FFT结果以及上面的分析计算,— 频率,幅度.相位…我们就可以写出信号的表达式了,它就是我们开始提供的信号。------ 信号重建

  1. 信号的时域采样点N和频域采样点数NFFT不同

%如果采样的时间周期是信号周期的倍数,可能泄露就会避免。频谱泄露是由于非整周期采样导致的。

% 我以前有个错误的观念:信号的时域采样点N必须和FFT的计算点数NFFT相同,才会给处理和解释带来便利。

% 原来是模型的不同产生的影响,采用模拟频率 f 建模不会产生末尾补零使得FFT频率不一致的问题,看下面的程序。

clear; close all;

% f1 = 20Hz, f2 = 40Hz %若 f1 = 15 可以观察频谱泄露情况

% (1)数据个数Ndata=32,FFT所用的采样点数NFFT=32
fs=240; %采样频率
Ndata=32; %数据长度
N=32; %FFT的数据长度
n=0:Ndata-1;t=n/fs; %数据对应的时间序列
x=0.5sin(2pi20t)+2sin(2pi40t); %时间域信号,x=0.5sin(2pi15t)+2sin(2pi40t); 可以发现频谱泄露
y=fft(x,N); %信号的Fourier变换
mag=abs(y); %求取振幅
f=(0:N-1)*fs/N; %真实频率
subplot(2,2,1),plot(f(1:N/2),mag(1:N/2)*2/N); %绘出Nyquist频率之前的振幅
xlabel(‘频率/Hz’);ylabel(‘振幅’);
title(‘Ndata=32 Nfft=32’);grid on;

% (2)数据个数Ndata=32,FFT所用的采样点数NFFT=126
Ndata=32; %数据个数
N=128; %FFT采用的数据长度
n=0:Ndata-1;t=n/fs; %时间序列
x=0.5sin(2pi20t)+2sin(2pi40t);
y=fft(x,N);
mag=abs(y);
f=(0:N-1)*fs/N; %真实频率
subplot(2,2,2),plot(f(1:N/2),mag(1:N/2)*2/N); %绘出Nyquist频率之前的振幅
xlabel(‘频率/Hz’);ylabel(‘振幅’);
title(‘Ndata=32 Nfft=128’);grid on;

% (3)数据个数Ndata = 136,FFT所用的采样点数NFFT=128
Ndata=136; %数据个数
N=128; %FFT采用的数据个数
n=0:Ndata-1;t=n/fs; %时间序列
x=0.5sin(2pi20t)+2sin(2pi40t);
y=fft(x,N);
mag=abs(y);
f=(0:N-1)*fs/N; %真实频率
subplot(2,2,3),plot(f(1:N/2),mag(1:N/2)*2/N); %绘出Nyquist频率之前的振幅
xlabel(‘频率/Hz’);ylabel(‘振幅’);
title(‘Ndata=136 Nfft=128’);grid on;

% (4)数据个数Ndata=136,FFT所用的采样点数NFFT=512
Ndata=136; %数据个数
N=512; %FFT所用的数据个数
n=0:Ndata-1;t=n/fs; %时间序列
x=0.5sin(2pi20t)+2sin(2pi40t);
y=fft(x,N);
mag=abs(y);
f=(0:N-1)fs/N; %真实频率
subplot(2,2,4),plot(f(1:N/2),mag(1:N/2)2/N); %绘出Nyquist频率之前的振幅
xlabel(‘频率/Hz’);ylabel(‘振幅’);
title(‘Ndata=136 Nfft=512’);grid on;
% (5)数据个数Ndata=136,FFT所用的采样点数NFFT=4096
Ndata=136; %数据个数
N=4096; %FFT所用的数据个数
n=0:Ndata-1;t=n/fs; %时间序列
x=0.5
sin(2
pi20t)+2sin(2pi40t);
y=fft(x,N);
mag=abs(y);
f=(0:N-1)*fs/N; %真实频率

figure,plot(f(1:N/2),mag(1:N/2)*2/N); %绘出Nyquist频率之前的振幅
xlabel(‘频率/Hz’);ylabel(‘振幅’);
title(‘Ndata=136 Nfft=512’);grid on;

  1. 信号的时域采样点N和频域采样点数NFFT不同 – 比较两种不同的信号模型

clear; close all;

% 该信号的数字周期 N = 8,模拟周期T = N*Ts = 0.008s ,实际频率 f = 125 Hz

w = pi/4;
N = 2pi/w; % N = 8
n = 0:N-1; % n = 0:N 可能会更好看一些,但是要清楚第N+1点可是下一个采样周期的第一个点
x = sin(n
w); % 不含有采样信息的x,补零的FFT对频谱有影响
h=plot(n, x,’-o’); %注意n没有定标,没有物理含义!
Fs = 1000; %采样频率为1000Hz
Ts = 1/Fs;
t = nTs; % t 时间序列的给法永远只有这么一种,请铭记!
T = N
Ts; %模拟周期T
f = wFs/(2pi); % 信号的真实频率f
figure; plot(t, x)
% freq = n*Fs/N - Fs/2; %频率序列的定标,注意此式子是本来面目,不要给此式子穿个马甲就不认识了,下面是此式子的变形
% freq = (n/N - 1/2)*Fs; freq = (n -N/2)/N * Fs; % 注意0~N-1时第N 点对应着 Fs, N/2 点对应着 Fs/2, Fs/N 就是频率分辨率
% freq = (n - N/2)/N; 就是归一化频率,从-0.5 到 0.5 - 1/N , 看看不是 -0.5 ~ 0.5 哦,实际结合硬件编程就要这样干

Nfft = 1024; % 此处 Nffft/N = 128,所以要对结果的频谱进行128点的抽取,才可以得到正确的频率定标!
X_Nfft = fftshift(abs(fft(x,Nfft)));
freqNormalized = ((0:Nfft-1) - Nfft/2)/Nfft;
freq_ = freqNormalized*Fs;
freq = freqNormalized(1:128:end)*Fs; % 结果和上面的结果完全相同 -500 -375 -250 -125 0 125 250 375

X_ = X_Nfft(1:128:end);

figure; plot(freq_, X_Nfft);grid

figure; plot(freq , X_);grid

%-------------------------------------------------------------------------
Ndata=136; %数据个数
N=4096; %FFT所用的数据个数
n=0:Ndata-1;t=n/fs; %时间序列
x =0.5sin(2pi20t)+2sin(2pi40t); %含有采样信息,补零后FFT对信号的频谱没影响
y=fft(x,N);
mag=abs(y);
f=(0:N-1)*fs/N; %真实频率

figure,plot(f(1:N/2),mag(1:N/2)*2/N); %绘出Nyquist频率之前的振幅
xlabel(‘频率/Hz’);ylabel(‘振幅’);
title(‘Ndata=136 Nfft=512’);grid on;

转载自:深入浅出解释FFT(四)——fft分析信号频率和相位

  • 1
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在LabVIEW中,使用FFT变换可以求得信号频率、幅值和相位。具体步骤如下: 1. 将信号输入到FFT模块中。 2. 对信号进行FFT变换。 3. 将变换后的结果转换为频率、幅值和相位信息。 4. 可以使用图形化界面显示结果,也可以将结果输出到文件或其他设备中。 需要注意的是,FFT变换的结果受到采样率、采样点数等因素的影响,因此在使用时需要根据实际情况进行调整。 ### 回答2: FFT(快速傅里叶变换)是一种常用的信号处理技术,能够将信号从时域转换为频域。在LabVIEW中,进行FFT变换求信号频率、幅值和相位非常简单,只需要几个步骤即可完成。 首先,需要准备一个待处理的信号。可以使用LabVIEW中的示波器模块或者从其他仪器中获取信号,也可以手工输入一个带有噪声的信号数据。 接着,将信号输入到FFT变换模块中。在LabVIEW中,可以通过选择“Signal Processing”类别下的“FFT”图标来创建一个FFT变换模块。将信号导入该模块后,就可以通过单击右侧的“View”按钮来查看FFT变换结果。 在FFT变换结果窗口中,有三个主要的信息:频率、幅值和相位频率指的是信号在频域中的分布情况,幅值表示在各个频率处的振幅大小,相位表示信号在不同频率处的相位差异。 在LabVIEW中,可以使用“Extract Single Tone Information”模块来提取FFT变换结果中的频率、幅值和相位信息。将FFT变换的结果导入该模块中,就可以将频率、幅值和相位分别输出为三个不同的浮点数。 最后,可以使用LabVIEW中的其他图形或控制模块来可视化输出的频率、幅值和相位信息。比如,在“Graph”图标中创建一个波形图,将频率和幅值输入该图形,就可以清晰地展示信号在不同频率处的振幅变化情况。同样地,也可以将相位信息输入到LabVIEW中的其他图形模块中,以便对信号的不同相位作出更加直观的分析。 ### 回答3: LabVIEW中FFT变换可以用于求解信号频率、幅值和相位FFT变换是一种数学方法,通过对信号进行傅里叶变换(Fourier Transform),将时域信号转换为频域信号,从而分析信号频率、幅值和相位。 在LabVIEW中,可以使用FFT VI对信号进行FFT转换。首先需要将信号输入FFT VI中,FFT VI会自动进行FFT计算,输出频域信号。然后,可以使用Magnitude和Phase VIs来求解信号的幅值和相位。 例如,假设有一段时域信号需要进行FFT变换分析,可以将此信号输入FFT VI中,并将输出连接至Magnitude和Phase VIs。Magnitude VI将计算频域信号的振幅谱,即各频率分量的幅值大小;Phase VI将计算各频率分量的相位角度。 在FFT VI中还可以设置一些参数,例如采样率和FFT大小等,以提高FFT的分辨率和准确性。如果需要更加详细的分析,可以使用其他LabVIEW内置的函数模块,例如Spectral Measurements VIs,以获取更加准确和详细的频域信息。 总之,FFT变换是LabVIEW中一种非常有用的信号处理方法,可以用于分析和求解各种信号频率、幅值和相位等信息。通过合理的选择参数和使用合适的函数模块,可以进行高质量、可靠的信号处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值