|
@ -2,7 +2,7 @@ |
|
|
%% $DATE : 14-Aug-2018 15:32:12 $ |
|
|
%% $DATE : 14-Aug-2018 15:32:12 $ |
|
|
%% $Revision : 1.00 $ |
|
|
%% $Revision : 1.00 $ |
|
|
%% DEVELOPED : 9.0.0.341360 (R2016a) |
|
|
%% DEVELOPED : 9.0.0.341360 (R2016a) |
|
|
%% FILENAME : band_pass_design.m |
|
|
%% FILENAME : band_elimination_design.m |
|
|
%% AEM : 8261 |
|
|
%% AEM : 8261 |
|
|
%% |
|
|
%% |
|
|
%% ========== DESIGN SPECIFICATIONS START ========== |
|
|
%% ========== DESIGN SPECIFICATIONS START ========== |
|
@ -46,6 +46,27 @@ specification_high_stop_radial_frequency = 2*pi* ... |
|
|
specification_min_stop_attenuation = 26+AEM(3)*5/9; % dB |
|
|
specification_min_stop_attenuation = 26+AEM(3)*5/9; % dB |
|
|
specification_max_pass_attenuation = 0.5+AEM(4)/18; % dB |
|
|
specification_max_pass_attenuation = 0.5+AEM(4)/18; % dB |
|
|
|
|
|
|
|
|
|
|
|
% Outputs results |
|
|
|
|
|
fprintf(['\n' '===== DESIGN SPECIFICATIONS =====' '\n' ... |
|
|
|
|
|
'Filter design specifications:\n' ... |
|
|
|
|
|
'Central frequency = %.3fHz = %.3frad/s\n' ... |
|
|
|
|
|
'Low pass frequency = %.3fHz = %.3frad/s\n' ... |
|
|
|
|
|
'High pass frequency = %.3fHz = %.3frad/s\n' ... |
|
|
|
|
|
'Low stop frequency = %.3fHz = %.3frad/s\n' ... |
|
|
|
|
|
'High stop frequency = %.3fHz = %.3frad/s\n' ... |
|
|
|
|
|
'Min stop attenuation = %.3fdB\n' ... |
|
|
|
|
|
'Max pass attenuation = %.3fdB\n'], ... |
|
|
|
|
|
specification_central_frequency, specification_central_radial_frequency, ... |
|
|
|
|
|
specification_low_pass_frequency, ... |
|
|
|
|
|
specification_low_pass_radial_frequency, ... |
|
|
|
|
|
specification_high_pass_frequency, ... |
|
|
|
|
|
specification_high_pass_radial_frequency, ... |
|
|
|
|
|
specification_low_stop_frequency, ... |
|
|
|
|
|
specification_low_stop_radial_frequency, ... |
|
|
|
|
|
specification_high_stop_frequency, ... |
|
|
|
|
|
specification_high_stop_radial_frequency, ... |
|
|
|
|
|
specification_min_stop_attenuation, specification_max_pass_attenuation); |
|
|
|
|
|
|
|
|
clear design_param_D |
|
|
clear design_param_D |
|
|
|
|
|
|
|
|
% ========== DESIGN SPECIFICATIONS END ========== |
|
|
% ========== DESIGN SPECIFICATIONS END ========== |
|
@ -73,19 +94,38 @@ design_geometric_central_radial_frequency = ... |
|
|
design_filter_bandwidth = specification_high_pass_radial_frequency- ... |
|
|
design_filter_bandwidth = specification_high_pass_radial_frequency- ... |
|
|
specification_low_pass_radial_frequency; % rad/s |
|
|
specification_low_pass_radial_frequency; % rad/s |
|
|
|
|
|
|
|
|
|
|
|
% Outputs results |
|
|
|
|
|
fprintf(['\n' '===== PROTOTYPE LOW PASS DESIGN SPECIFICATIONS =====' '\n' ... |
|
|
|
|
|
'The prototype low pass filter will be designed with the\n' ... |
|
|
|
|
|
'normalized stop radial frequency %.3frad/s, the normalized\n' ... |
|
|
|
|
|
'pass radial frequency is equal to 1rad/s.\n' ... |
|
|
|
|
|
'Min and max attenuation specifications remain the same.\n' ... |
|
|
|
|
|
'\nThe filter bandwidth and geometric central frequency are also\n' ... |
|
|
|
|
|
'calculated for later usage:\n' ... |
|
|
|
|
|
'Filter bandwidth = %.3fHz = %.3frad/s\n' ... |
|
|
|
|
|
'Geometric central frequency = %.3fHz = %.3frad/s\n' ... |
|
|
|
|
|
'\nThe central frequency calculated is equal to the one given\n' ... |
|
|
|
|
|
'in the specifications part, confirming the specifications\n' ... |
|
|
|
|
|
'where calculated correctly.\n'], ... |
|
|
|
|
|
prototype_normalized_stop_radial_frequency, ... |
|
|
|
|
|
design_filter_bandwidth/(2*pi), design_filter_bandwidth, ... |
|
|
|
|
|
design_geometric_central_radial_frequency/(2*pi), ... |
|
|
|
|
|
design_geometric_central_radial_frequency); |
|
|
|
|
|
|
|
|
% ========== PROTOTYPE LOW PASS DESIGN SPECIFICATIONS END ========== |
|
|
% ========== PROTOTYPE LOW PASS DESIGN SPECIFICATIONS END ========== |
|
|
|
|
|
|
|
|
%% ========== PROTOTYPE LOW PASS DESIGN START ========== |
|
|
%% ========== PROTOTYPE LOW PASS DESIGN START ========== |
|
|
% The calculated low pass design specifications have a form fit for a low |
|
|
% The calculated low pass design specifications have a form fit for a low |
|
|
% pass Chebyshev filter design (the pass radial frequency is normalized to |
|
|
% pass Chebyshev filter design (the pass radial frequency is normalized to |
|
|
% one). |
|
|
% unity). |
|
|
% Designs the prototype normalized filter. |
|
|
% Designs the prototype normalized filter. |
|
|
|
|
|
|
|
|
% Calculates the filter's order using the eq. 9-83 |
|
|
% Calculates the filter's order using the eq. 9-83 |
|
|
design_filter_order = ceil(acosh(((10^ ... |
|
|
temp_filter_order = acosh(((10^ ... |
|
|
(specification_min_stop_attenuation/10)-1)/(10^ ... |
|
|
(specification_min_stop_attenuation/10)-1)/(10^ ... |
|
|
(specification_max_pass_attenuation/10)-1))^(1/2))/ ... |
|
|
(specification_max_pass_attenuation/10)-1))^(1/2))/ ... |
|
|
acosh(prototype_normalized_stop_radial_frequency)); |
|
|
acosh(prototype_normalized_stop_radial_frequency); |
|
|
|
|
|
design_filter_order = ceil(temp_filter_order); |
|
|
|
|
|
|
|
|
% Calculates epsilon parameter using the eq. 9-76 |
|
|
% Calculates epsilon parameter using the eq. 9-76 |
|
|
epsilon_parameter = sqrt(10^(specification_max_pass_attenuation/10)-1); |
|
|
epsilon_parameter = sqrt(10^(specification_max_pass_attenuation/10)-1); |
|
@ -190,11 +230,38 @@ else % Even number of poles |
|
|
end |
|
|
end |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
% Outputs results |
|
|
|
|
|
fprintf(['\n' '===== PROTOTYPE LOW PASS DESIGN =====' '\n' ... |
|
|
|
|
|
'A prototype low pass Chebyshev filter is designed with the\n' ... |
|
|
|
|
|
'specifications previously calculated.\n\n' ... |
|
|
|
|
|
'Filter order = %.3f\n' ... |
|
|
|
|
|
'Filter order ceiling = %d\n' ... |
|
|
|
|
|
'Epsilon parameter = %.3f\n' ... |
|
|
|
|
|
'Alpha parameter = %.3f\n' ... |
|
|
|
|
|
'Radial frequency at which half power occurs = %.3frad/s\n' ... |
|
|
|
|
|
'Butterworth angles are ' char(177) '%.2f' char(176) ' and ' ... |
|
|
|
|
|
char(177) '%.2f' char(176) '\n'], ... |
|
|
|
|
|
temp_filter_order, design_filter_order, ... |
|
|
|
|
|
epsilon_parameter, alpha_parameter, ... |
|
|
|
|
|
design_half_power_radial_frequency, design_butterworth_angles(1,1), ... |
|
|
|
|
|
design_butterworth_angles(1,2)); |
|
|
|
|
|
|
|
|
|
|
|
fprintf('\nLow pass Chebyshev poles found:\n'); |
|
|
|
|
|
for i=1:low_pass_prototype_number_of_poles |
|
|
|
|
|
fprintf(['Pole %d:\t' '%.3f' char(177) ... |
|
|
|
|
|
'%.3fi, radial frequency = %.3f, Q = %.3f\n'], ... |
|
|
|
|
|
i, low_pass_prototype_poles_real_parts(1,i), ... |
|
|
|
|
|
low_pass_prototype_poles_imaginary_parts(1,i), ... |
|
|
|
|
|
low_pass_prototype_poles_radial_frequencies(1,i), ... |
|
|
|
|
|
low_pass_prototype_poles_Q(1,i)); |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
% Clears unneeded variables from workspace |
|
|
% Clears unneeded variables from workspace |
|
|
clearVars = {'prototype_normalized_stop_radial_frequency', ... |
|
|
clearVars = {'prototype_normalized_stop_radial_frequency', ... |
|
|
'epsilon_parameter', 'alpha_parameter', 'theta'}; |
|
|
'epsilon_parameter', 'alpha_parameter', 'theta', 'temp_filter_order'}; |
|
|
clear(clearVars{:}) |
|
|
clear(clearVars{:}) |
|
|
clear clearVars |
|
|
clear clearVars |
|
|
|
|
|
|
|
|
% ========== PROTOTYPE LOW PASS DESIGN END ========== |
|
|
% ========== PROTOTYPE LOW PASS DESIGN END ========== |
|
|
|
|
|
|
|
|
%% ========== LOW PASS TO HIGH PASS TRANSFORMATION START ========== |
|
|
%% ========== LOW PASS TO HIGH PASS TRANSFORMATION START ========== |
|
@ -240,13 +307,28 @@ for i=1:high_pass_prototype_number_of_poles |
|
|
sind(high_pass_prototype_poles_angles(1,i)); |
|
|
sind(high_pass_prototype_poles_angles(1,i)); |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
% Outputs results |
|
|
|
|
|
fprintf(['\n' '===== LOW PASS TO HIGH PASS TRANSFORMATION =====' '\n' ... |
|
|
|
|
|
'The prototype low pass Chebyshev filter is transformed into\n' ... |
|
|
|
|
|
'a high pass Chebyshev using the transformation S = 1/s.\n']); |
|
|
|
|
|
|
|
|
|
|
|
fprintf('\nHigh pass Chebyshev poles found:\n'); |
|
|
|
|
|
for i=1:low_pass_prototype_number_of_poles |
|
|
|
|
|
fprintf(['Pole %d:\t' '%.3f' char(177) ... |
|
|
|
|
|
'%.3fi, radial frequency = %.3f, Q = %.3f, angle = ' ... |
|
|
|
|
|
char(177) '%.2f' char(176) '\n'], ... |
|
|
|
|
|
i, high_pass_prototype_poles_real_parts(1,i), ... |
|
|
|
|
|
high_pass_prototype_poles_imaginary_parts(1,i), ... |
|
|
|
|
|
high_pass_prototype_poles_radial_frequencies(1,i), ... |
|
|
|
|
|
high_pass_prototype_poles_Q(1,i), ... |
|
|
|
|
|
high_pass_prototype_poles_angles(1,i)); |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
% Clears unneeded variables from workspace |
|
|
% Clears unneeded variables from workspace |
|
|
% |
|
|
|
|
|
clearVars = {'i', 'high_pass_prototype_poles_radial_frequencies', ... |
|
|
clearVars = {'i', 'high_pass_prototype_poles_radial_frequencies', ... |
|
|
'high_pass_prototype_poles_Q', 'high_pass_prototype_poles_angles'}; |
|
|
'high_pass_prototype_poles_Q', 'high_pass_prototype_poles_angles'}; |
|
|
clear(clearVars{:}) |
|
|
clear(clearVars{:}) |
|
|
clear clearVars |
|
|
clear clearVars |
|
|
% |
|
|
|
|
|
clear -regexp ^low_pass_prototype_ |
|
|
clear -regexp ^low_pass_prototype_ |
|
|
|
|
|
|
|
|
% ========== LOW PASS TO HIGH PASS TRANSFORMATION END ========== |
|
|
% ========== LOW PASS TO HIGH PASS TRANSFORMATION END ========== |
|
@ -348,6 +430,26 @@ for i=1:high_pass_prototype_number_of_poles |
|
|
end |
|
|
end |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
% Outputs results |
|
|
|
|
|
fprintf(['\n' '===== HIGH PASS TO BAND ELIMINATION TRANSFORMATION =====' '\n' ... |
|
|
|
|
|
'The high pass Chebyshev filter is transformed into a band elimination\n' ... |
|
|
|
|
|
'Chebyshev using the Geffe algorithm to transform the poles.\n']); |
|
|
|
|
|
|
|
|
|
|
|
fprintf('\nBand elimination Chebyshev poles found:\n'); |
|
|
|
|
|
for i=1:band_elimination_number_of_poles |
|
|
|
|
|
fprintf(['Pole %d:\t' 'radial frequency = %.3f, Q = %.3f, angle = ' ... |
|
|
|
|
|
char(177) '%.2f' char(176) '\n'], ... |
|
|
|
|
|
i, band_elimination_poles_radial_frequencies(1,i), ... |
|
|
|
|
|
band_elimination_poles_Q(1,i), ... |
|
|
|
|
|
band_elimination_poles_angle(1,i)); |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
fprintf('\nTransfer function zeros:\n'); |
|
|
|
|
|
for i=1:length(band_elimination_transfer_function_zeros) |
|
|
|
|
|
fprintf(['Zero %d:\t' '0%+.3fi\n'], ... |
|
|
|
|
|
i, imag(band_elimination_transfer_function_zeros(1,i))); |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
% Clears unneeded variables from workspace |
|
|
% Clears unneeded variables from workspace |
|
|
clearVars = {'i', 'temp_index'}; |
|
|
clearVars = {'i', 'temp_index'}; |
|
|
clear(clearVars{:}) |
|
|
clear(clearVars{:}) |
|
@ -355,6 +457,7 @@ clear clearVars |
|
|
clear -regexp ^high_pass_prototype_ |
|
|
clear -regexp ^high_pass_prototype_ |
|
|
clear -regexp ^geffe_ |
|
|
clear -regexp ^geffe_ |
|
|
clear -regexp ^transformation_ |
|
|
clear -regexp ^transformation_ |
|
|
|
|
|
|
|
|
% ========== POLES TRANSFORMATION END ========== |
|
|
% ========== POLES TRANSFORMATION END ========== |
|
|
|
|
|
|
|
|
%% ========== ZEROS-POLES GROUPING START ========== |
|
|
%% ========== ZEROS-POLES GROUPING START ========== |
|
@ -386,7 +489,7 @@ clear -regexp ^transformation_ |
|
|
|
|
|
|
|
|
%% ========== UNITS IMPLEMENTATION START ========== |
|
|
%% ========== UNITS IMPLEMENTATION START ========== |
|
|
% AEM(3) = 6, so the circuits shown in 7.21 and 7.23 are going to be used |
|
|
% AEM(3) = 6, so the circuits shown in 7.21 and 7.23 are going to be used |
|
|
% for the low pass notch units. |
|
|
% for the notch units. |
|
|
|
|
|
|
|
|
% High pass notch units 1 and 3 |
|
|
% High pass notch units 1 and 3 |
|
|
% Initializes necessary arrays, each array is 1X2, the first element (1,1) |
|
|
% Initializes necessary arrays, each array is 1X2, the first element (1,1) |
|
@ -594,6 +697,63 @@ for i=1:2 |
|
|
low_pass_notch_units_gains_high(1,i); |
|
|
low_pass_notch_units_gains_high(1,i); |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
% Outputs results |
|
|
|
|
|
fprintf(['\n' '===== UNITS IMPLEMENTATION =====' '\n' ... |
|
|
|
|
|
'Pole-zero pairing results in the implementation of two high\n' ... |
|
|
|
|
|
'pass notch (HPN) units and two low pass notch (LPN) units.\n' ... |
|
|
|
|
|
'\nUnits implementation details:\n']); |
|
|
|
|
|
for i=1:band_elimination_number_of_poles |
|
|
|
|
|
if i==1 || i==3 |
|
|
|
|
|
fprintf(['Unit %d (HPN):\n' ... |
|
|
|
|
|
'\tPole radial frequency = %.3f\n'... |
|
|
|
|
|
'\tPole Q = %.3f\n' ... |
|
|
|
|
|
'\tTransfer function zero = 0' char(177) '%.3fi\n' ... |
|
|
|
|
|
'\tCircuit elements:\n' ... |
|
|
|
|
|
'\t\tR1 = %.3fOhm\n' ... |
|
|
|
|
|
'\t\tR2 = %.3fOhm\n' ... |
|
|
|
|
|
'\t\tR3 = %.3fOhm\n' ... |
|
|
|
|
|
'\t\tR4 = %.3fOhm\n' ... |
|
|
|
|
|
'\t\tC = %.7fF\n' ... |
|
|
|
|
|
'\t\tC1 = %.9fF\n' ... |
|
|
|
|
|
'\tUnit gain at high frequencies = %.3f\n'], ... |
|
|
|
|
|
i, band_elimination_poles_radial_frequencies(1,i), ... |
|
|
|
|
|
band_elimination_poles_Q(1,i), ... |
|
|
|
|
|
abs(imag(band_elimination_transfer_function_zeros(1,i))), ... |
|
|
|
|
|
high_pass_notch_units_R1(1,(i+1)/2), ... |
|
|
|
|
|
high_pass_notch_units_R2(1,(i+1)/2), ... |
|
|
|
|
|
high_pass_notch_units_R3(1,(i+1)/2), ... |
|
|
|
|
|
high_pass_notch_units_R4(1,(i+1)/2), ... |
|
|
|
|
|
high_pass_notch_units_C(1,(i+1)/2), ... |
|
|
|
|
|
high_pass_notch_units_C1(1,(i+1)/2), ... |
|
|
|
|
|
high_pass_notch_units_gain_high(1,(i+1)/2)); |
|
|
|
|
|
else |
|
|
|
|
|
fprintf(['Unit %d (LPN):\n' ... |
|
|
|
|
|
'\tPole radial frequency = %.3f\n'... |
|
|
|
|
|
'\tPole Q = %.3f\n' ... |
|
|
|
|
|
'\tTransfer function zero = 0' char(177) '%.3fi\n' ... |
|
|
|
|
|
'\tCircuit elements:\n' ... |
|
|
|
|
|
'\t\tR1 = %.3fOhm\n' ... |
|
|
|
|
|
'\t\tR2 = %.3fOhm\n' ... |
|
|
|
|
|
'\t\tR3 = %.3fOhm\n' ... |
|
|
|
|
|
'\t\tR4 = %.3fOhm\n' ... |
|
|
|
|
|
'\t\tR5 = %.3fOhm\n' ... |
|
|
|
|
|
'\t\tC = %.7fF\n' ... |
|
|
|
|
|
'\tUnit gain at low frequencies = %.3f\n' ... |
|
|
|
|
|
'\tUnit gain at high frequencies = %.3f\n'], ... |
|
|
|
|
|
i, band_elimination_poles_radial_frequencies(1,i), ... |
|
|
|
|
|
band_elimination_poles_Q(1,i), ... |
|
|
|
|
|
abs(imag(band_elimination_transfer_function_zeros(1,i))), ... |
|
|
|
|
|
low_pass_notch_units_resistors_1(1,i/2), ... |
|
|
|
|
|
low_pass_notch_units_resistors_2(1,i/2), ... |
|
|
|
|
|
low_pass_notch_units_resistors_3(1,i/2), ... |
|
|
|
|
|
low_pass_notch_units_resistors_4(1,i/2), ... |
|
|
|
|
|
low_pass_notch_units_resistors_5(1,i/2), ... |
|
|
|
|
|
low_pass_notch_units_capacitors(1,i/2), ... |
|
|
|
|
|
low_pass_notch_units_gains_low(1,i/2), ... |
|
|
|
|
|
low_pass_notch_units_gains_high(1,i/2)); |
|
|
|
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
% Clears unneeded variable from workspace |
|
|
% Clears unneeded variable from workspace |
|
|
clearVars = {'i', 'temp', 'unit_index', 'normalized_transfer_function_zero'}; |
|
|
clearVars = {'i', 'temp', 'unit_index', 'normalized_transfer_function_zero'}; |
|
|
clear(clearVars{:}) |
|
|
clear(clearVars{:}) |
|
@ -622,6 +782,17 @@ total_transfer_function = series(series(series( ... |
|
|
|
|
|
|
|
|
total_transfer_function = total_transfer_function*unit_adjustment_gain; |
|
|
total_transfer_function = total_transfer_function*unit_adjustment_gain; |
|
|
|
|
|
|
|
|
|
|
|
fprintf(['\n' '===== GAIN ADJUSTMENT =====' '\n' ... |
|
|
|
|
|
'A gain adjustment unit is needed to achieve 0dB attenuation at ' ... |
|
|
|
|
|
'pass band.\n' ... |
|
|
|
|
|
'We arbitrarily choose to use a 10KOhm series resistor.\n' ... |
|
|
|
|
|
'The feedback resistor is %.3fOhm to get a gain equal to %.3fdB\n'], ... |
|
|
|
|
|
unit_adjustment_feedback_resistor, unit_adjustment_gain); |
|
|
|
|
|
|
|
|
|
|
|
% ========== GAIN ADJUSTMENT END ========== |
|
|
|
|
|
|
|
|
|
|
|
%% ========== TRANSFER FUNCTIONS START ========== |
|
|
|
|
|
|
|
|
%{ |
|
|
%{ |
|
|
ltiview(high_pass_notch_units_transfer_functions(1,1), ... |
|
|
ltiview(high_pass_notch_units_transfer_functions(1,1), ... |
|
|
high_pass_notch_units_transfer_functions(1,2)); |
|
|
high_pass_notch_units_transfer_functions(1,2)); |
|
@ -649,16 +820,14 @@ ltiview(high_pass_notch_units_transfer_functions(1,1), ... |
|
|
|
|
|
|
|
|
%ltiview(total_transfer_function); |
|
|
%ltiview(total_transfer_function); |
|
|
|
|
|
|
|
|
% |
|
|
%{ |
|
|
plot_transfer_function(total_transfer_function, ... |
|
|
plot_transfer_function(total_transfer_function, ... |
|
|
[specification_central_frequency ... |
|
|
[specification_low_stop_frequency ... |
|
|
band_elimination_poles_radial_frequencies(1,1)/(2*pi) ... |
|
|
|
|
|
design_half_power_radial_frequency*specification_low_pass_radial_frequency/(2*pi) ... |
|
|
|
|
|
specification_low_stop_frequency ... |
|
|
|
|
|
specification_low_pass_frequency ... |
|
|
specification_low_pass_frequency ... |
|
|
|
|
|
specification_central_frequency ... |
|
|
specification_high_pass_frequency ... |
|
|
specification_high_pass_frequency ... |
|
|
specification_high_stop_frequency]); |
|
|
specification_high_stop_frequency]); |
|
|
% |
|
|
%} |
|
|
|
|
|
|
|
|
% Clears unneeded variable from workspace |
|
|
% Clears unneeded variable from workspace |
|
|
clearVars = {'total_transfer_function'}; |
|
|
clearVars = {'total_transfer_function'}; |
|
@ -666,4 +835,4 @@ clear(clearVars{:}) |
|
|
clear clearVars |
|
|
clear clearVars |
|
|
clear -regexp _transfer_functions$ |
|
|
clear -regexp _transfer_functions$ |
|
|
|
|
|
|
|
|
% ========== GAIN ADJUSTMENT END ========== |
|
|
% ========== TRANSFER FUNCTIONS END ========== |