簡體   English   中英

Matlab繪制對數啁啾的對數

[英]Matlab plot log magnitude of chirp

我創建了一個與matlab幫助頁面完全相同的對數啁啾。

t = 0:0.001:10;      % 10 seconds @ 1kHz sample rate
fo = 10; f1 = 400;   % Start at 10Hz, go up to 400Hz
X = chirp(t,fo,10,f1,'logarithmic');
figure(2);
spectrogram(X,256,200,256,1000,'yaxis');

譜圖

然后我使用以下代碼將其帶到頻域,該代碼適用於我的其他應用程序。

fft_prep = fftshift(fft(X));
fft_mag = abs(fft_prep);
pos_fft = fft_mag(1:ceil(length(fft_mag)/2));
db_fft = 20*log10(pos_fft);
figure(1);
plot(db_fft);

我很驚訝地發現以下圖表看起來令人興奮1kHz-5kHz:

SpectrumAnalyzer

我對matlab中的啁啾功能並不熟悉,並且想知道是否有人看到了我遺漏的明顯事物。 歡迎任何其他指針。

chirp功能沒有問題......

您只需要根據頻率值繪制db_fft,而不是矢量索引=)。

plot(linspace(fo,f1,length(db_fft)), db_fft);

在此輸入圖像描述

我還測試了使用其他FFT方法計算信號的FFT,它們也指示了0到400 Hz之間的范圍。

更新:

IMO,我發現在視覺上更容易不以dB或功率(周期圖)繪圖。 這是一個很好的例子和我計算時域信號FFT的goto方法:mathworks.se/help/matlab/ref/fft.html

響應:

經過一番思考,我同意我的答案不正確,但不是因為你說的原因。 頻域中的x軸不應該達到啁啾的實際長度(或一半,或dubbel或類似的東西)。 頻域中的x軸應達到信號采樣率(Fs / 2)的一半,這是您的義務,以確保您以兩倍於您希望/希望的最高頻率的采樣頻率對信號進行采樣解決。

換句話說,假設您的FFT是時域信號的長度的相同/兩倍/一半,這是不正確的,因為我們可以選擇任意數量的頻點來表示FFT,最佳做法是長度= N ^ 2( 2)的功率,用於快速計算。 想一想,為什么在計算FFT時甚至需要知道時間值? 你不! 您只需要采樣頻率(應將其設置為Fs = 1000 btw,而不是Fs = 0.001)。

我上面的回答是不正確的,它應該是:

plot(linspace(0, Fs/2, length(db_fft)), db_fft)

您寫的是length(t)/(2 * Tfinal),而不是Fs / 2。 (幾乎)與Fs / 2相同,但不是正確的處理方式=)。

這是我的轉到FFT方法(值不以dB為單位)。

function [X,f] = myfft(x,Fs,norm)
    % usage: [X, f] = myfft(x,Fs,norm);
    %        figure(); plot(f,X)
    % norm: 'true' normalizes max(amplitude(fft))=1, default=false.
    if nargin==2
        norm=false;
    end
    L = length(x); NFFT = 2^nextpow2(L);
    f = Fs/2*linspace(0,1,NFFT/2+1);
    %f =0:(Fs/NFFT):Fs/2;
    X = fft(x,NFFT)/L; X = 2*abs(X(1:NFFT/2+1));
    if norm==true; X = X/max(abs(X)); end
end

這是[Xfft,f] = myfft(X,Fs); 情節(F,Xfft); 注意,根據NyQuist定理,返回頻率倉矢量具有max(f)= Fs / 2(任何比Fs / 2更高的頻率都不能被解析)。

在此輸入圖像描述

我有幾個錯誤,但並非所有錯誤都已解決。 在嘗試了更多代碼之后,這是我想出的解決方案。

我添加了一些其他變量以使設置更具模塊化。

Tfinal = 10;
Fs = 1/1000;
t = 0:Fs:Tfinal;      % 10 seconds @ 1kHz sample rate
fo = 10; f1 = 400;   % Start at 10Hz, go up to 400Hz
X = chirp(t,fo,Tfinal,f1,'linear');

當我繪制幅度與空間的關系時,空間需要匹配實際啁啾信號的長度,而不僅僅是從低頻到高頻。 因為向量t的長度為1000,並且在FFT之后我們使用正的一半,所以啁啾信號是500長而不是400,其中linspace直到f1將表明。

fft_prep = fftshift(fft(X));
fft_mag = abs(fft_prep);
pos_fft = fft_mag(ceil(length(fft_mag)/2)+1:length(fft_mag));
db_fft=20*log10(pos_fft);
figure(1);
plot(linspace(0,length(t)/(2*Tfinal),length(db_fft)), db_fft);

我還進行了前面提到的修復,以獲取FFT的正值而不是負值。 這個情節:

在此輸入圖像描述

這可以准確地繪制exciting激勵10Hz-400Hz的圖形。 通過查看極端情況並將其線性化,可以更清楚地看到它。 嘗試在沒有 linspace校正的情況下 ,采樣頻率為100,范圍為10-25。

在此輸入圖像描述

校正

在此輸入圖像描述

順便提及,從FFT提取原始啁啾振幅可能是有用的。 例如,如果您正在以某個設備的頻率進行音頻掃描,並且您想知道每個頻率的響應的幅度和相位(如Pspice givs you)。 簡而言之,幅度是啁啾/(Fs * N)的^ 2 = abs(FFT)^ 2 * 4 *帶寬,其中Fs是采樣頻率,N是FFT中的點數。 例如,200到400Hz的啁啾帶寬是200Hz。

如果你想知道這個問題,請從Parseval的theorum開始:平均時間信號的sqr = PSD下的面積。 因此,a ^ 2/2 =和(abs(FFT)^ 2)/ N ^ 2,其中a是掃頻信號(例如,啁啾)的峰值幅度。 如果啁啾在頻率分布上是線性的而不是對數的,則FFT是平坦的,如上圖所示。 那么我們可以用Nb * abs(FFT)^ 2 / N ^ 2代替和,其中Nb是啁啾占據的頻率倉的數量,而abs(FFT)是FFT的幅度,這對所有人都是相同的啁啾占據的頻率區間。 利用一個頻率倉的帶寬為Fs / N的事實,我們得到啁啾的帶寬是Nb * Fs / N. 上面的結果現在很容易從這里推導出來。

MATLAB的有關fft文檔實際上提供了簡單的指令,這些指令通常適用於任何chirp (例如二次或線性)選擇:

Fs = 1000;            % Sampling frequency                    
T = 1/Fs;             % Sampling period       
L = 1500;             % Length of signal
t = (0:L-1)*T;        % Time vector

要分析的信號示例:

S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
X = S + 2*randn(size(t));

計算FFT:

Y   = fft(X);       % Calculate FFT
P2  = abs(Y/L);
P1  = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);

頻率向量計算為

f = Fs*(0:(L/2))/L;

如果您想生成Bode幅度圖,首先應將頻率轉換為[rad / s],將fft的結果轉換為[dB]:

fRad = f*2*pi;
Pdb = 20*log10(P1);

然后制作一個波德圖(我建議使用散射,考慮到結果的潛在嘈雜性)

figure
scatter(fRad,Pdb)
set(gca,'xscale','log') 
grid on; grid minor
xlabel('Frequency [rad/s]')
ylabel('Magnitude [dB]')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM