Designing a bandpass filter in Matlab

13 次查看(过去 30 天)
Hi,
I am trying to implement an FIR bandpass filter, with a pass band from ~350KHz to ~700KHz.
For that, I am using the fir1 function.
My signal is sampled at 10Mhz and the number of sample points are ~126M.
For the bandpass filter I use the following code:
%% testing
Fs = 1e7; % sampling frequency
L = 126204866; % length of signal
% Parameters for the implementation of a BandPass filter
f3 = 300e3; % low cut-off frequency for Bandpass: 700e3, 300e3
f4 = 750e3; % high cut-off frequency for Bandpass: 1450e3, 750e3
fpass = [f3 f4];
hc = fir1(200,fpass/Fs,"bandpass");
% Break the frequency axis into "L" bins/buckets
f = (-0.5:1/L:0.5-1/L)*Fs; % create the frequency vector (frequency X-axis)
Y = 20*log10(abs(fftshift(fft(hc,L))));
figure;
reduce_plot(f,Y);
axis([0 Fs/2 -60 20])
title('Filter Frequency Response')
grid on
If I use the frequencies f3 = 300KHz and f4 = 750 KHz, I get the following filter frequency response:
As can be seen the 3db attenuation is at ~170KHz and ~355KHz.
On the other hand, if I use frequencies f3 = 700KHz and f4 = 1450 KHz, I get the desired filter frequency response:
As can be seen the 3db attenuation is at ~370KHz and ~705KHz.
It seems that I need to double the input frequencies I use in fir1 function to get the desired frequency response.
Could somebody explain what is the cause for this?
I am using Matlab R2021b.
Thank you in advance for your response and time.
-Nassos

采纳的回答

Star Strider
Star Strider 2022-6-27
It took me a while to figure out what the problem was, and it turns out to be that the passband frequencies must be normalised by the Nyquist frequency, while the posted code normalises them by the sampling frequency. The result is that the frequencies in the uncorrected code are half of what they should be.
%% testing
Fs = 1e7; % sampling frequency
L = 126204866; % length of signal
% Parameters for the implementation of a BandPass filter
f3 = 300e3; % low cut-off frequency for Bandpass: 700e3, 300e3
f4 = 750e3; % high cut-off frequency for Bandpass: 1450e3, 750e3
fpass = [f3 f4];
hc = fir1(200,fpass/(Fs/2),"bandpass");
% Break the frequency axis into "L" bins/buckets
f = (-0.5:1/L:0.5-1/L)*Fs; % create the frequency vector (frequency X-axis)
Y = 20*log10(abs(fftshift(fft(hc,L))));
[h,w] = freqz(hc, 1, 2^16, Fs);
idx = find(w >= mean(fpass), 1, 'first');
idxv = [1 idx; idx+1 numel(w)];
format short eng
absh = abs(h);
for k = 1:2
idxr = idxv(k,1) : idxv(k,2);
hpf(k) = interp1(mag2db(absh(idxr)), w(idxr), -6);
% figure
% plot(w(idxr),mag2db(absh(idxr)))
% grid
end
fprintf('Half-Power (-6 dB) Frequencies = [%8.3E, %8.3E]',hpf)
Half-Power (-6 dB) Frequencies = [2.999E+05, 7.499E+05]
figure;
freqz(hc, 1, 2^16, Fs)
set(subplot(2,1,1), 'XLim',[0 1]*1E+6)
yline(subplot(2,1,1), -3)
xline(subplot(2,1,1),hpf,'-r')
set(subplot(2,1,2), 'XLim',[0 1]*1E+6)
title('Filter Frequency Response')
grid on
Also, the bulit-in freqz function is the correct way to depict discrete filter Bode plots in MATLAB.
.

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Digital Filter Analysis 的更多信息

产品


版本

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by