home *** CD-ROM | disk | FTP | other *** search
- program maxfilter; { Program Maximizes Possible Ripple Frequencies }
- { While Maintaining Required Attenuation Values }
- { Specified in Stop Band }
-
- { Jeff Crawford TRW February 14, 1985 }
-
- { StopBand Requirements Are Specified by Operator. This Program Calculates }
- { if The Difference Between That Obtainable [ Using Chebycheff Approx.] and }
- { That Required is > 0 At All Specified StopBand Frequencies. If This }
- { Margin is Not > 0 Then a Higher Order Filter is Required. If the Margin is}
- { > 0 the StopBand Frequency at Which the Smallest Margin Exists is }
- { Determined by a Simple Search. First, Using the Previously Given Upper }
- { Ripple Frequency, Linear Interpolation of the [Loss Function - Required Att}
- { is Used to Move Out the Lower Ripple Frequency to a Point Where the }
- { Equation Above is Identically Zero. A New Geometric Center Frequency is }
- { Calculated. Another Determination of Which Upper StopBand Frequency Has }
- { the Least Margin With the Newly Calculated Lower wp is Made. Linear }
- { Interpolation of the Upper StopBand Frequency is Done With the Previously }
- { Calculated New Lower Ripple Frequency, wp_lo. This Entire Procedure is }
- { Continued Until Convergence. }
-
- { REFERENCES }
-
- { [1] "Dissipation Loss of Chebyshev BandPass Filters", Harold Schumacher, }
- { Microwave Journal, pp 41-43, August, 1977. }
- { [2] " Microwave Filters, Impedance Matching Networks, and Coupling }
- { Structures", G.L. Matthaei, Leo Young, E. M. T. Jones, McGraw Hill }
- { Book Company, 1964. }
- { [3] "Principles of Active Network Synthesis and Design", Gobind Daryanani}
- { John Wiley & Sons, 1976. }
-
-
- type matrix_a = array[1..16] of real;
-
- var wp_lo_max,wp_hi_min : real; { Lower, Upper Ripple Freqs; Begin }
- wp_lo,wp_hi : real; { Iterated New Ripple Freqs }
- eta,L_db : real; { dB Ripple in }
- N_lo,N_hi : integer; { # Requirements in Stop-Bands }
- i,j,ii : integer; { Loop Counters }
- Freq : matrix_a; { Frequencies in Stop-Bands }
- Att : matrix_a; { Attenuations in Stop-Bands }
- delta_Db : matrix_a; { Differences in Attenuation }
- { & That Specified as Needed }
- del : real;
- order : integer; { Filter Order }
- wp : real; { Ripple Frequency in Iterration }
- wp_new : real; { Newly Solved for Ripple Freq }
- Flag1 : boolean; { Determines if Delta-dB < 0 }
- ord_lo,ord_hi : integer; { Lower, Up }
- No,Num_lo,Num_hi : integer; { Freq of Minimum Attenuation }
- min : real; { Minimum Attenuation in StopBand }
- wp_new_1,wp_new_2 : real; { New wp Frequencies }
- wo_geom : real; { Geometric Center Frequency }
- temp : real; { Temporary Holding Variable }
- stat : real; { Aborts Loop Upon Convergence }
- wp_lo_save,wp_hi_save : real; { wp's From Previous Iteration }
- freq_margin : real; { Percentage Error Allowed in Calc }
- { When Exceeded, Leaves Loop }
- stat_ptr : string[1]; { Printer Status }
- IL : real; { Center of Band Insertion Loss }
- Qu : real; { Unloaded Resonator Q }
- inkey :char;
-
-
- Function Log10( X:Real ):Real;
- begin
- Log10:=0.434294482*Ln( X );
- end;
- {///////////////////////////////////////////////}
-
- Function Cosh( X:Real ):Real;
- var temp : Real;
- begin
- temp:=exp( X );
- Cosh:= 0.5 * ( temp + 1/temp );
- end;
- {///////////////////////////////////////////////}
-
- Function Sinh( X: real): real;
- var temp: real;
- begin
- temp:= exp(X);
- Sinh:= 0.5*(temp - 1/temp );
- end;
- { ////////////////////////////////////////////// }
-
- Function Tanh( X: real): real;
- begin
- Tanh:= Sinh(X)/Cosh(X);
- end;
- { ////////////////////////////////////////////// }
-
- Function XtoY( X,Y:Real ):Real;
- begin
- XtoY:= exp( Y * Ln( X ) );
- end;
- {///////////////////////////////////////////////}
-
- Function ArcCosh( X:Real ):Real;
- begin
- ArcCosh:= Ln( X + sqrt( sqr(X) - 1 ) );
- end;
- {////////////////////////////////////////////////}
-
- Procedure Iterate_Freq_1( wp:real; No: integer); { Calculation of Iterated }
- { wp_lo for the Lower StopBand; Next Iterate High StopBand with Next R }
-
- var wp_1,wp_2,wp_3 : real; { Frequency Variables in Linear Interpol }
- L1,L2,L3 : real; { Losses at Frequency Variables Above }
- error : real; { Differences in Frequencies }
- del : real; { Attenuation in Loss Function }
- Timer : integer; { Aborts if No Convergence }
-
- Label 10;
-
- Function Loss( wp: real; No: integer ): real;
-
- { wp is Ripple Freq in Use }
-
- var temp: real;
-
- begin
- temp:= abs(wo_geom/(wp_hi-wp)*(wo_geom/Freq[No] - Freq[No]/wo_geom));
- del:= 10.0*Log10(1+sqr(eta*Cosh(order*ArcCosh(temp)))) - Att[No];
- Loss:= del;
- end;
-
- begin
- del:= 1;
- wo_geom:= sqrt(wp*wp_hi); { Calculate Geometric Center Frequency }
- L1:= Loss(wp,No); { Loss at wp_lo = dB Ripple }
- wp_1:= wp;
- wp_2:= 0.5*(wp + Freq[No]);{ Select Another Frequency Which Contains Zero }
- wo_geom:= sqrt(wp_2*wp_hi); { Recalculate Geometric Center }
- L2:= Loss(wp_2,No);
- Timer:= 1;
- while abs(del) > 0.01 do
- begin
- if Timer >= 10 then goto 10;
- wp_3:= (L1*wp_2 - L2*wp_1)/(L1-L2);
- wo_geom:= sqrt(wp_3*wp_hi); { Must Recalculate Geometric Center }
- L3:= Loss(wp_3,No);
- if L1*L3 > 0.0 then
- begin
- L1:= L3;
- wp_1:= wp_3;
- if wp_1 > wp_lo_max then wp_1:= wp_lo_max;
- end;
- if L1*L3 <= 0.0 then
- begin
- L2:= L3;
- wp_2:= wp_3;
- if wp_2 > wp_lo_max then wp_2:= wp_lo_max;
- end;
- Timer:= Timer + 1;
- end;
- 10: wp_new:= wp_3; { New Lower Ripple Frequency }
- if (del < 0.01) and ( Timer = 1 ) then wp_new:= wp_2; { In Case wp_2 is }
- end; { Right On }
-
- { ================================================================== }
-
- Procedure Iterate_Freq_2( wp: real; No: integer); { For Upper StopBand }
- var wp_1,wp_2,wp_3 : real; { Frequency Variables in Linear Interpol }
- L1,L2,L3 : real; { Losses at Frequency Variables Above }
- error : real; { Differences in Frequencies }
- del : real; { Attenuation in Loss Function }
- Timer : integer; { Aborts if No Convergence }
-
- label 10;
-
- Function Loss( wp: real; No: integer ): real;
- var temp: real;
-
- begin
- temp:= abs(wo_geom/(wp-wp_lo)*(wo_geom/Freq[No]-Freq[No]/wo_geom));
- del:= 10.0*Log10(1+sqr(eta*Cosh(order*ArcCosh(temp)))) - Att[No];
- Loss:= del;
- end;
-
- begin
- del:= 1;
- wo_geom:= sqrt(wp_lo*wp);
- L1:= Loss(wp,No); { Loss at wp_hi = dB Ripple }
- wp_1:= wp;
- wp_2:= 0.5*(wp + Freq[No]);
- wo_geom:= sqrt(wp_2*wp_lo);
- L2:= Loss(wp_2,No);
- Timer:= 1;
- while abs(del) > 0.01 do
- begin
- if Timer >= 10 then goto 10;
- wp_3:= (L1*wp_2 - L2*wp_1)/(L1-L2);
- wo_geom:= sqrt(wp_3*wp_lo);
- L3:= Loss(wp_3,No);
- if L1*L3 > 0.0 then
- begin
- L1:= L3;
- wp_1:= wp_3;
- if wp_1 < wp_hi_min then wp_1:= wp_hi_min;
- end;
- if L1*L3 <= 0.0 then
- begin
- L2:= L3;
- wp_2:= wp_3;
- if wp_2 < wp_hi_min then wp_2:= wp_hi_min;
- end;
- Timer:= Timer + 1;
- end;
- 10: wp_new:= wp_3;
- if ( del < 0.01) and ( Timer = 1 ) then wp_new:= wp_2;
- end;
-
- { ================================================================== }
-
- procedure Inser_Loss( var order:integer; Am_dB:real);
-
- type matrix = array[0..20] of real;
-
- var W : real; { Fractional Bandwidth }
- wo : real; { Geometric Center Frequency }
- a,b : matrix; { Array Holding Values - Matthaei 4.05-02 }
- g : matrix; { Elemental Values }
- Beta : real;
- gamma : real;
- gamma2 : real;
- k : integer; { Loop Counter }
- Sum : real;
-
- begin
- W:= (wp_hi-wp_lo)/wo_geom;
- Beta:= Ln(1/Tanh( Am_dB/17.37));
- gamma:= sinh(beta/(2*order)); { Eq 4.05-02 Matthaei }
- gamma2:= sqr(gamma);
- for k:= 1 to order do
- begin
- a[k]:= sin((2*k-1)*Pi/(2*order));
- b[k]:= gamma2 + sqr(sin(k*Pi/order));
- end;
- g[0]:= 1.0;
- g[1]:= 2*a[1]/gamma;
- for k:= 2 to order do
- begin
- g[k]:= 4*a[k-1]*a[k]/(b[k-1]*g[k-1]);
- end;
- if ( order mod 2 = 1 ) then
- g[order + 1]:= 1.0
- else
- g[order + 1]:= sqr(1.0/tanh(0.25*Beta));
- sum:= 0.0;
- for k:= 1 to order + 1 do
- begin
- sum:= sum + g[k];
- end;
- IL:= 4.343*sum*4*g[0]*g[order+1]/(W*Qu*sqr(g[0]+g[order+1]));
- end;
-
- { ================================================================== }
-
-
-
- procedure maxi;
- var IO_Error : integer;
-
- begin
- clrscr;
- gotoXY(1,8);
- writeln;
- writeln(' P A S S B A N D M A X I M I Z E R');
- writeln(' Version 2.0.2 ');
- writeln(' Jeff Crawford TRW ');
- delay(1000);
- clrscr;
- gotoXY(10,10);
- write('Enter Minimum f-low and Maximum f-high in MHz ');
- {$I-}
- repeat
- IO_Error:=0;
- readln(wp_lo_max,wp_hi_min);
- IO_Error:=IOResult;
- if IO_Error <>0 then writeln ('Error; please re-enter data correctly.');
- until IO_Error=0;
- {$I+}
- wp_lo:= wp_lo_max;
- wp_hi:= wp_hi_min;
- write(' ');
- write('Enter dB Ripple in Passband & % Freq Error ');
- {$I-}
- repeat
- IO_Error:=0;
- readln(L_db,Freq_margin);
- IO_Error:=IOResult;
- if IO_Error <>0 then writeln ('Error; please re-enter data correctly.');
- until IO_Error=0;
- {$I+}
- write(' ');
- write('Enter Approx Resonator Unloaded Q ');
- {$I-}
- repeat
- IO_Error:=0;
- readln(Qu);
- IO_Error:=IOResult;
- if IO_Error <>0 then writeln ('Error; please re-enter data correctly.');
- until IO_Error=0;
- {$I+}
- freq_margin:= freq_margin*0.01;
- eta:= sqrt(XtoY(10.0,0.1*L_db)-1.0);
- write(' ');
- write('Enter Number of Lower Stop-Band Freq Requirements ');
- {$I-}
- repeat
- IO_Error:=0;
- readln(N_lo);
- IO_Error:=IOResult;
- if IO_Error <>0 then writeln ('Error; please re-enter data correctly.');
- until IO_Error=0;
- {$I+}
- write(' ');
- write('Enter Number of Upper Stop-Band Freq Requirements ');
- {$I-}
- repeat
- IO_Error:=0;
- readln(N_hi);
- IO_Error:=IOResult;
- if IO_Error <>0 then writeln ('Error; please re-enter data correctly.');
- until IO_Error=0;
- {$I+}
- write(' ');
- write('Enter Lower, Upper Bounds on Filter Order ');
- {$I-}
- repeat
- IO_Error:=0;
- readln(ord_lo,ord_hi);
- IO_Error:=IOResult;
- if IO_Error <>0 then writeln ('Error; please re-enter data correctly.');
- until IO_Error=0;
- {$I+}
- order:= ord_lo;
- writeln;
- write(' ');
- write('Is a Hard Copy of Results Desired Y/N ? ');
- readln(stat_ptr);
- stat_ptr:= upcase(stat_ptr);
- clrscr;
- writeln;
- writeln(' Enter Lower Stop-Band Freqs & Respective Attenuations ');
- writeln;
- for i:= 1 to N_lo do { Input Stop-Band Attenuation Requirements }
- begin
- gotoXY(25,i+5);
- write('[',i,'] = ');
- {$I-}
- repeat
- IO_Error:=0;
- readln(Freq[i],Att[i]);
- IO_Error:=IOResult;
- if IO_Error <>0 then writeln ('Error; please re-enter data correctly.');
- until IO_Error=0;
- {$I+}
- end;
- clrscr;
- writeln;
- writeln(' Enter Upper Stop-Band Freqs & Respective Attenuations ');
- writeln;
- for i:= 1 to N_hi do
- begin
- gotoXY(25,i+5);
- write('[',i,'] = ');
- {$I-}
- repeat
- IO_Error:=0;
- readln(Freq[i+N_lo],Att[i+N_lo]);
- IO_Error:=IOResult;
- if IO_Error <>0 then writeln ('Error; please re-enter data correctly.');
- until IO_Error=0;
- {$I+}
- end;
- clrscr;
- writeln;
- write(' Min wp = ',wp_lo_max:8:3,' Max wp = ',wp_hi_min:8:3);
- writeln(' dB Ripple = ',L_db:5:2);
- writeln(' Resonator Qu = ',Qu:6:2);
- writeln;
- writeln(' Stop-Band Attenuation Requirements ');
- writeln;
- write(' Frequency Attenuation ');
- writeln;
- for i:= 1 to N_lo + N_hi do
- begin
- write(' F',i,' ');
- writeln(Freq[i]:10:3,' MHz . . . . . . . .. . . . ',Att[i]:5:2,' dB');
- end;
- for i:= 1 to 2 do
- begin
- write('=============================================================');
- writeln('=================');
- end;
- writeln;
- write('Order Low Fp Up Fp Loss dB ');
- for i:= 1 to N_lo+N_hi do
- begin
- write(' F',i,' ');
- end;
- writeln;
- writeln;
- if stat_ptr = 'Y' then
- begin
- writeln(LST);
- write(LST,' Min wp = ',wp_lo_max:8:3,' Max wp = ',wp_hi_min:8:3);
- writeln(LST,' dB Ripple = ',L_db:5:2);
- writeln(LST,' Resonator Qu = ',Qu:6:2);
- writeln(LST);
- writeln(LST,' Stop-Band Attenuation Requirements ');
- writeln(LST);
- write(LST,' Frequency Attenuation ');
- writeln(LST);
- for i:= 1 to N_lo + N_hi do
- begin
- write(LST,' F',i,' ');
- writeln(LST,Freq[i]:10:3,' MHz . . . . . . . .. . . . ',Att[i]:5:2,' dB');
- end;
- for i:= 1 to 2 do
- begin
- write(LST,'=============================================================');
- writeln(LST,'=================');
- end;
- writeln(LST);
- write(LST,'Order Low Fp Up Fp Loss dB ');
- for i:= 1 to N_lo+N_hi do
- begin
- write(LST,' F',i,' ');
- end;
- writeln(LST);
- writeln(LST);
- end;
- order:= ord_lo;
- while order <= ord_hi do { For Order Selected }
- begin
- Flag1:= False;
- del:= 1.0;
- min:= 1.0E10;
- wo_geom:= sqrt(wp_lo_max*wp_hi_min);
- for i:= 1 to N_lo do { If Margins First Time Through Are Negative }
- begin { Need A Higher Order Filter }
- wp:= wo_geom/(wp_hi_min-wp_lo_max);
- wp:= abs(wp*(wo_geom/Freq[i] - Freq[i]/wo_geom));
- del:= 10.0*Log10( 1 + sqr(eta*Cosh(Order*Arccosh(wp))));
- delta_dB[i]:= del - Att[i];
- if delta_dB[i] < 0.0 then Flag1:= True;
- if delta_dB[i] < min then
- begin
- min:= delta_dB[i];
- Num_lo:= i;
- end;
- end; { Flag1 Is Set if Any Negative Margins Appear }
- del:= 1.0;
- min:= 1.0E10;
- for i:= 1 to N_hi do
- begin
- wp:= wo_geom/(wp_hi_min-wp_lo_max);
- wp:= abs(wp*(wo_geom/Freq[i+N_lo]-Freq[i+N_lo]/wo_geom));
- del:= 10.0*Log10( 1 + sqr(eta*Cosh(Order*Arccosh(wp))));
- delta_dB[i+N_lo]:= del - Att[i+N_lo];
- if delta_dB[i+N_lo] < 0.0 then Flag1:= True;
- if delta_db[i+N_lo] < min then
- begin
- min:= delta_dB[i+N_lo];
- Num_hi:= i+N_lo;
- end;
- end;
- if Flag1 = True then { Output Best Possible Performance For Neg Margin }
- begin
- write('',order:2,' ');
- for i:= 1 to N_lo+N_hi do
- begin
- write(Delta_dB[i]+Att[i]:8:3,' ');
- end;
- writeln;
- if stat_ptr = 'Y' then
- begin
- write(LST,'',order:2,' ');
- for i:= 1 to N_lo+N_hi do
- begin
- write(LST,Delta_dB[i]+Att[i]:8:3,' ');
- end;
- writeln(LST);
- end;
- end;
- if (Flag1 = False) then { When Filter Order is High Enough, Optimize }
- begin { Ripple BandWidths for Best Passband Width }
- wo_geom:= sqrt(wp_lo*wp_hi);
- stat:= 1.0E10;
- while stat > freq_margin do
- begin
- wp_lo_save:= wp_lo;
- wp_hi_save:= wp_hi;
- Iterate_Freq_1(wp_lo,Num_lo); { Find New Lower wp }
- wp_lo:= wp_new;
- del:= 1.0;
- min:= 1.0E10;
- wo_geom:= sqrt(wp_lo*wp_hi);
- for i:= 1 to N_hi do { Find Upper StopBand Freq With Least Margin}
- begin
- wp:= wo_geom/(wp_hi-wp_lo);
- wp:= abs(wp*(wo_geom/Freq[i+N_lo] - Freq[i+N_lo]/wo_geom));
- del:= 10.0*Log10( 1 + sqr(eta*Cosh(Order*Arccosh(wp))));
- delta_dB[i+N_lo]:= del - Att[i+N_lo];
- if delta_dB[i+N_lo] < min then
- begin
- min:= delta_dB[i+N_lo];
- Num_hi:= i+N_lo;
- end;
- end;
- Iterate_Freq_2(wp_hi,Num_hi); { Calculate New Upper wp }
- wp_hi:= wp_new;
- del:= 1.0;
- min:= 1.0E10;
- wo_geom:= sqrt(wp_lo*wp_hi);
- for i:= 1 to N_lo do { Evaluate Which Lower Freq Has Min Margin }
- begin
- wp:= wo_geom/(wp_hi-wp_lo);
- wp:= abs(wp*(wo_geom/Freq[i]-Freq[i]/wo_geom));
- del:= 10.0*Log10( 1 + sqr(eta*Cosh(Order*Arccosh(wp))));
- delta_dB[i]:= del - Att[i];
- if delta_db[i] < min then
- begin
- min:= delta_dB[i];
- Num_lo:= i;
- end;
- end;
- stat:=(abs(wp_lo-wp_lo_save)+abs(wp_hi-wp_hi_save))/wo_geom;
- wp_new_1:= wp_lo;
- wp_new_2:= wp_hi;
- end;
- Inser_Loss(order,L_dB);
- for i:= 1 to N_lo+N_hi do
- begin
- temp:= wo_geom/(wp_hi-wp_lo);
- temp:= abs(temp*(wo_geom/Freq[i]-Freq[i]/wo_geom));
- del:= 10.0*Log10( 1 + sqr(eta*Cosh(Order*Arccosh(temp))));
- delta_dB[i]:= del - Att[i];
- end;
- write('',order:2,' ',wp_new_1:8:3,' ',wp_new_2:8:3,'');
- write(IL:8:3,' ');
- for i:= 1 to N_lo+N_hi do
- begin
- write(Delta_dB[i]+Att[i]:8:3,' ');
- end;
- writeln;
- if stat_ptr = 'Y' then
- begin
- write(LST,'',order:2,' ',wp_new_1:8:3,' ',wp_new_2:8:3,'');
- write(LST,IL:8:3,' ');
- for i:= 1 to N_lo+N_hi do
- begin
- write(LST,Delta_dB[i]+Att[i]:8:3,' ');
- end;
- writeln(LST);
- end;
- end;
- wp_lo:= wp_lo_max;
- wp_hi:= wp_hi_min;
- Flag1:= False;
- order:= order + 1;
- end;
- write(' ');
- writeln(' CR to Continue');
- readln(wp_lo);
- end;{end maxi}
-
-
- var ink : boolean;
-
- begin {main}
- repeat
- ink:=false;
- maxi;
- writeln(' To rerun the program, type R ');
- read (inkey);
- if inkey='r' then ink:=true;
- if inkey='R' then ink:=true;
- until not ink;
- end.
-
-
-
-
-
-
-
-
-