How to plot the actual frequency range for the FFT plot?

Suppose I have a complex linear frequency modulated signal, where the frequency of it sweeps from 9.975 GHz to 10.025 GHz with 50 MHz bandwidth and the time duration is 10 . As my sampling frequency is fixed as 51.2 MHz, the FFT plot of the signal is shown below,
The corresponding code is given below.
clear all;
close all;
clc;
%% Signal parameter
c = 3e8; % speed of light
fc= 10e9; % carrier frequency
lambda = c/fc; % wave length
B = 50e6; % bandwidth
Tchirp = 1e-5; % duration time
slope = B / Tchirp; % slope
Nr = 513; % number
fs = (Nr-1)/Tchirp; % sampling frequency
t = linspace(0,Tchirp,Nr);
t(Nr)=[];
St = exp(1j*2*pi*((fc-B/2)*t + (slope*t.^2)/2)); % signal
St_all = [St];
figure; % check fft plot
plot(abs(fft(St_all)));
As my signal ranges from 9.975 GHz to 10.025 GHz. What is the actual frequency for x axis here? Why the FFT plot will include the current period of signal and an adjacent period here? Meanwhile, is there any way to present the whole 50 MHz of signal in a single FFT plot?

回答 (2 件)

Star Strider
Star Strider 2023 年 4 月 16 日

0 投票

One approach —
%% Signal parameter
c = 3e8; % speed of light
fc= 10e9; % carrier frequency
lambda = c/fc; % wave length
B = 50e6; % bandwidth
Tchirp = 1e-5; % duration time
slope = B / Tchirp; % slope
Nr = 513; % number
fs = (Nr-1)/Tchirp; % sampling frequency
t = linspace(0,Tchirp,Nr);
t(Nr)=[];
St = exp(1j*2*pi*((fc-B/2)*t + (slope*t.^2)/2)); % signal
St_all = [St];
L = numel(St_all)
L = 512
FT_St = fft(St_all)/L;
Fv = linspace(0, 1, fix(L/2)+1)*fs/2; % Frequency Vector
Iv = 1:numel(Fv); % Index Vector
figure; % check fft plot
plot(Fv, abs(fft(St_all(Iv))));
xlabel('Frequency (Hz)')
ylabel('Magnitude (units)')
xlim([min(Fv) max(Fv)])
The code for ‘Fv’ originates in the documentation for fft in R2015b. I have used it since, although other ways to calculate the frequency for a one-sided fft that produce the same result are equally valid. The ‘Iv’vector simply make subsequent addressing easier. It is not required.
.

7 件のコメント

奥 刘
奥 刘 2023 年 4 月 16 日
編集済み: 奥 刘 2023 年 4 月 16 日
Thank you for your answer! So, through the operation above, we can achieve the frequency response for half of the sampling frequency. I am also wondering if there is a neat way to calculate the frequency axis for the period of the actual radio frequency signal, which is centered 10 GHz?
Star Strider
Star Strider 2023 年 4 月 16 日
My pleasure!
Probably the easiest way to do that is to eimply use xlim to limit the displayed frequencies. However here ‘fs’ is 51.2 MHz, much too low to accurately calculate a signal of 10 GHz (10000 MHz). The sampling frequency has to be increased to at least 20 GHz (and preferably much higher) to calculate it. Then the frequency calculation for the plot call in the code above should work without further modification.
.
奥 刘
奥 刘 2023 年 4 月 17 日
Yes, you are right. By Nyquist sampling with 20 GHz, we can directly give the plot with 10 GHz presented. But for a bandpass sampling (In reality, 20 GHz is basically impossible), the fft plot with 51.2 MHz sampling frequency just shows one of the many periods (Am I getting it right?). So, to plot the period with 10 GHz, maybe we can just add the corresponding number of periods?
Star Strider
Star Strider 2023 年 4 月 17 日
Thank you!
I doubt that adding the number of periods will solve that particular problem. The sampling frequency must be at least 20 GHz, and preferably 50 GHz for good measure. The filter can be made to work at those frequencies (passive waveguide filters exist for that purpose) and while floating-point calculations will be a bit more difficult at those sampling rates, they should be possible. Your current code may simply need to be scaled up appropriately.
You can also experiment with the modulate function.
Paul
Paul 2023 年 4 月 17 日
Two questions:
How would the one-sided transform apply here? St_all is complex so its FFT is not conjugate symmetric.
What is the purpose of this line
plot(Fv, abs(fft(St_all(Iv))));
that takes the fft of only the first half (perhaps to within a sample) of St_all? Why is the second half of St_all being chopped off?
奥 刘
奥 刘 2023 年 4 月 17 日
@Star Strider Thanks! I will check the modulate function
Star Strider
Star Strider 2023 年 4 月 17 日
My pleasure!

サインインしてコメントする。

Paul
Paul 2023 年 4 月 16 日
編集済み: Paul 2023 年 4 月 16 日

0 投票

clear all;
close all;
clc;
%% Signal parameter
c = 3e8; % speed of light
fc= 10e9; % carrier frequency
lambda = c/fc; % wave length
B = 50e6; % bandwidth
Tchirp = 1e-5; % duration time
slope = B / Tchirp; % slope
Nr = 513; % number
fs = (Nr-1)/Tchirp; % sampling frequency
t = linspace(0,Tchirp,Nr);
t(Nr)=[];
St = exp(1j*2*pi*((fc-B/2)*t + (slope*t.^2)/2)); % signal
St_all = [St];
Frequency vector corresponding to St_all
N = numel(St_all);
f = (0:(N-1))/N*fs;
figure; % check fft plot
plot(f,abs(fft(St_all)));
xlabel('Hz')
The reason that all the action is around 4.22e7 Hz is because the sampling frequency
fs
fs = 5.1200e+07
is way too small relative the base sinusoidal frequency
fc - B/2
ans = 9.9750e+09
The 4.22e7 result is the aliased frequency.
If we make the sampling frequency more than two times larger than the base frequency
fs = (fc - B/2)*5 % sampling frequency
fs = 4.9875e+10
then we get this result:
t = linspace(0,Tchirp,round(Tchirp*fs));
St = exp(1j*2*pi*((fc-B/2)*t + (slope*t.^2)/2)); % signal
St_all = [St];
Frequency vector corresponding to St_all
N = numel(St_all);
f = (0:(N-1))/N*fs;
figure; % check fft plot
plot(f,abs(fft(St_all)))
xlabel('Hz')
xlim([9e9 11e9])
xline(fc-B/2,'r')

製品

リリース

R2022b

タグ

質問済み:

2023 年 4 月 16 日

コメント済み:

2023 年 4 月 17 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by