home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HAM Radio 1
/
HamRadio.cdr
/
tech
/
eepub05
/
ciranl.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1984-12-10
|
13KB
|
384 lines
program CirAnl; { Performs Nodal Circuit Analysis for Freq Resp }
{ Jeff Crawford December 10, 1984 }
{ }
{ Version 1.0 }
{ }
{ REFERENCES }
{ }
{ [1] "Unify Two-Port Calculations", D. J. Daruvala, Electronic }
{ Design, January 4, & January 18, 1974 - Two Articles }
{ [2] "High-Frequency Amplifiers, 2nd Edition", Ralph S. Carson,}
{ John Wiley & Sons, 1982 }
type matrix = array[1..25,1..25] of real;
vector = array[1..100] of real;
XYData = record
XX,YY: real;
end;
stat = string[1];
var L,Cap : matrix; { Inductance, Capacitance Terms Sqmodel }
Fyi,Fyr : matrix; { Admittance Matrices; Real, Imag }
F,F_low,F_high: real; { Frequency Information }
F_inc : real; { Increment of Frequency }
Nodes : integer;{ Number of Nodes in Circuit; Passed from}
{ Sqmodel Main Program }
omega : real; { Radian Frequency }
N : integer;{ Parameter in Node Reduction Routine }
{ N Starts at Nodes and is Reduced by 1 }
{ Until Arriving at N=2 for a Two-Port }
No_turns : integer;{ # Turns in Inductor - Passed from Main}
A,B : matrix; { Equiv of Fyr,Fyi Matrices; Used in }
{ Matrix Reduction Routine to a 2 x 2 }
i,j : integer;{ Used in Looping }
Freq,Mag : vector; { Arrays to Hold Information of Z v.s. F}
Ans,Ans1,Ans2 : stat; { Controls Function Routing }
Num : integer; { Number of Data Points Store on Disk }
Procedure Write_File( X,Y: vector);
var j : integer;
write_file : file of XYData;
read_file : file of XYData;
file_rec : XYData;
file_name : string[10];
file_size : integer;
OK : Boolean;
Ans1,Ans2 : string[1]; { Controls Program Routing }
label 1,2;
begin
2: clrscr;
gotoXY(10,10);
write('Write Data to What File ? ');
readln(file_name);
assign(write_file,file_name);
{$I-} Reset(write_file) {$I+};
OK:= (IOresult = 0); { Determines if File Already Exists }
if OK then
begin
clrscr;
gotoXY(10,10);
write('File Already Exists . . . Overwrite ? Y / N ');
readln(Ans2);
Ans2:= upcase(Ans2);
if Ans2 <> 'Y' then goto 1;
end;
assign(write_file,file_name);
rewrite(write_file);
with file_rec do
begin
for j:= 1 to Num do { Writes Data to Disk File }
begin
XX:= X[j];
YY:= X[j];
write(write_file,file_rec);
end;
end;
flush(write_file);
close(write_file);
1: if Ans2 = 'N' then
begin
clrscr;
gotoXY(10,10);
write('Write Data to Different File Y / N ? ');
readln(Ans1);
Ans1:= upcase(Ans1);
if Ans1 = 'Y' then goto 2;
end;
end;
Procedure Swap(var X1,Y1: real); { Used to Swap Rows & Columns to }
{ Change Input and/or Output Terminals }
{ for Calculation; Declared "var" so }
{ Switch is Made in Major Matrices }
var XX: real;
begin
XX:= X1;
X1:= Y1;
Y1:= XX;
end;
Procedure Save_C(V: real; i,j: integer); { Saves Capacitors }
var temp: real;
begin
temp:= omega*V;
Fyi[i,i]:= Fyi[i,i] + temp;
Fyi[j,j]:= Fyi[j,j] + temp;
Fyi[i,j]:= Fyi[i,j] - temp;
Fyi[j,i]:= Fyi[j,i] - temp;
end;
Procedure Save_L(V: real; i,j: integer);
var temp: real;
begin
temp:= -1.0/(omega*V);
Fyi[i,i]:= Fyi[i,i] + temp;
Fyi[j,j]:= Fyi[j,j] + temp;
Fyi[i,j]:= Fyi[i,j] - temp;
Fyi[j,i]:= Fyi[j,i] - temp;
end;
Procedure Fill_Caps(var N: integer);
var i : integer;
begin
for i:= 2 to N-1 do
begin
Save_C(cap[i-1,i-1],i,0);
end;
for i:= 2 to N-2 do
begin
Save_C(cap[i-1,i], i, i+1);
end;
end;
Procedure Fill_Inductors(var N: integer);
var i : integer;
Ind_val : real;
begin
Save_L(0.5*L[1,1],1,2);
Save_L(0.5*L[N-2,N-2], N-1,N);
for i:= 2 to N-2 do
begin
Ind_val:= 1/(0.5*(L[i-1,i-1] + L[i,i])) + 1.0/L[i-1,i];
{ i,j are Coupled Turn Designators }
Save_L(1.0/Ind_val,i,i+1);
end;
for i:= 2 to N-1 do
begin
for j:= i+2 to N-1 do
begin
Save_L(L[i-1,j-1], i,j);
end;
end;
end;
Procedure Reduce_Mat(In_node,Out_node:integer; N:integer; var A,B:matrix);
{ Reduces Beginning N*N Floating Admittance Matrix to an Equivalent Two - }
{ Port Representation by Proper Matrix Reduction Techniques Discussed in }
{ the References Sited. After the Necessary Swapping to Place Input Node }
{ in Columns/Row 1 and Output Node in 2, Reference Node in 3, The Starting}
{ Matrix is Reduced Down to a Two-Port Representation. }
var Den : real; { Magnitude of Yrr }
r : integer; { Row & Column Being Reduced }
i,j : integer;
LL : integer; { Largest Diagonal Element Row - Better }
XX1 : real; { Real Part of Common Term Subtracted From }
{ Yps in Reduction Process }
YY1 : real; { Imag Part of Common Term Subtracted From }
{ Yps in Reduction Process }
S1,S : real; { Tests for Largest Diagonal Element; Done to }
{ Retain as Much Accuracy as Possible in the }
{ Reduction Process }
begin
if (In_node <> 1) or (Out_node <> 2) then { Swap In & Out }
begin
for j:= 1 to N do
begin
Swap(A[1,j], A[In_node,j]);
Swap(B[1,j], B[In_node,j]);
Swap(A[2,j], A[Out_node,j]);
Swap(B[2,j], B[Out_node,j]);
end;
for i:= 1 to N do
begin
Swap(A[i,1], A[i,In_node]);
Swap(B[i,1], B[i,In_node]);
Swap(A[i,2], A[i,Out_node]);
Swap(B[i,2], B[i,Out_node]);
end;
end;
while N > 2 do { Finds Largest Diagonal Element in Rows Remaining }
{ to be Reduced to Enhance Accuracy and Performs the }
{ Necessary Swapping }
begin
LL:= 3;
S:= abs( A[LL,LL] ) + abs( B[LL,LL] );
if N > 3 then
begin
for i:= 4 to N do
begin
S1:= abs( A[i,i] ) + abs( B[i,i] );
if S1 > S then
begin
S:= S1;
LL:= i;
end;
end;
end;
if LL <> N then
begin
for j:= 1 to N do
begin
Swap( A[LL,j],A[N,j]);
Swap( B[LL,j],B[N,j]);
end;
for i:= 1 to N do
begin
Swap( A[i,LL], A[i,N]);
Swap( B[i,LL],B[i,N]);
end;
end;
Den:= sqr(A[N,N]) + sqr(B[N,N]); { Beginning of Main Reduction }
r:= N;
N:= N - 1;
for i:= 1 to N do
begin
if (A[i,r] <> 0) or (B[i,r] <> 0) then
begin
XX1:= (A[i,r]*A[r,r] + B[r,r]*B[i,r])/Den;
YY1:= (A[r,r]*B[i,r] - A[i,r]*B[r,r])/Den;
for j:= 1 to N do
begin
if (A[r,j]<> 0) or (B[r,j]<> 0) then
begin
A[i,j]:= A[i,j] - A[r,j]*XX1 + B[r,j]*YY1;
B[i,j]:= B[i,j] - A[r,j]*YY1 - B[r,j]*XX1;
end;
end;
end;
end;
end;
end;
Procedure Out_put(Ans2: stat; var FYr,FYi:matrix );
begin
write(' ',F:6:3,' ',Fyr[1,1]:6:4,' ',Fyi[1,1]:6:4,' ',Fyr[1,2]:6:4);
write(' ',Fyi[1,2]:6:4,' ',Fyr[2,1]:6:4,' ',Fyi[2,1]:6:4);
writeln(' ',Fyr[2,2]:6:4,' ',Fyi[2,2]:6:4);
if Ans2 = 'Y' then
begin
write(LST,' ',F:6:3,' ',Fyr[1,1]:6:4,' ',Fyi[1,1]:6:4,' ',Fyr[1,2]:6:4);
write(LST,' ',Fyi[1,2]:6:4,' ',Fyr[2,1]:6:4,' ',Fyi[2,1]:6:4);
writeln(LST,' ',Fyr[2,2]:6:4,' ',Fyi[2,2]:6:4);
end;
end;
{ //////////////////////////////////////////////////////////////////// }
{ ////////////////////// MAIN /////////////////// }
{ ////////////////////// BLOCK /////////////////// }
{ //////////////////////////////////////////////////////////////////// }
begin
No_turns:= 4;
L[1,2]:= 3.08175E-11;
L[1,3]:= 2.54812E-11;
L[1,4]:= 2.27640E-11;
L[2,3]:= 4.78563E-11;
L[2,4]:= 3.85507E-11;
L[3,4]:= 6.57417E-11;
L[1,1]:= 7.7183E-11;
L[2,2]:= 1.2684E-10;
L[3,3]:= 1.8074E-10;
L[4,4]:= 2.378E-10;
cap[1,2]:= 6.21531E-15;
cap[2,3]:= 8.56065E-15;
cap[3,4]:= 1.0906E-14;
cap[2,0]:= 1.41149E-15;
cap[3,0]:= 1.85961E-15;
cap[1,1]:= 4.02368E-15;
cap[4,4]:= 9.6381E-15;
for i:= 1 to 25 do
begin
for j:= 1 to 25 do
begin
Fyr[i,j]:= 0.0;
Fyi[i,j]:= 0.0;
A[i,j]:= 0.0;
B[i,j]:= 0.0;
end;
end;
Ans2:= 'N';
clrscr;
gotoXY(10,10);
write('Enter Lower, Upper, & Freq-Increment, GHz ');
readln(F_low, F_high, F_inc);
F:= F_low;
writeln;
write(' Is a Hard-Copy Desired Y / N ');
readln(Ans2);
Ans2:= upcase(Ans2);
Nodes:= No_turns + 2;
Num:= 0;
clrscr;
gotoXY(1,2);
write(' Two - Port Admittance Parameters ');
writeln;
write(' Freq Y11 Y12 ');
writeln(' Y21 Y22');
write(' GHz Real Imag Real Imag ');
writeln(' Real Imag Real Imag');
writeln;
if Ans2 = 'Y' then
begin
writeln(LST,' Two - Port Admittance Parameters ');
writeln(LST);
write(LST,' Freq Y11 Y12 ');
writeln(LST,' Y21 Y22');
write(LST,' GHz Real Imag Real Imag ');
writeln(LST,' Real Imag Real Imag');
writeln(LST);
end;
while F<= F_high do
begin
Num:= Num + 1;
Omega:= F*2*Pi*1.0E9;
N:= Nodes;
for i:= 1 to N do
begin
for j:= 1 to N do
begin
Fyr[i,j]:= 0.0;
Fyi[i,j]:= 0.0;
end;
end;
Fill_Caps(N);
Fill_inductors(N);
Reduce_Mat(1,Nodes,N,Fyr,Fyi);
Freq[Num]:= F;
Mag[Num]:= -1.0/Fyi[1,1];
Out_put(Ans2,Fyr,Fyi);
F:= F + F_inc;
end;
write(' ');
writeln(' Any Key to Continue ');
repeat
delay(100);
until keypressed;
clrscr;
gotoXY(10,10);
write('Store Data to Disk ? Y/N ');
readln(Ans);
Ans:= upcase(Ans);
if Ans = 'Y' then Write_file(Freq,Mag);
end.