diff options
| -rw-r--r-- | octave/rf_bpf.m | 37 | ||||
| -rw-r--r-- | octave/rf_design.m | 77 | ||||
| -rw-r--r-- | octave/rf_vhf_amp.m | 206 | ||||
| -rw-r--r-- | octave/rf_vhf_pa.m | 111 |
4 files changed, 0 insertions, 431 deletions
diff --git a/octave/rf_bpf.m b/octave/rf_bpf.m deleted file mode 100644 index e0a39ba..0000000 --- a/octave/rf_bpf.m +++ /dev/null @@ -1,37 +0,0 @@ -% rtlsdr_bpf.m -% -% David Rowe 24 August 2018 -% -% Calculate component values for cascaded HP-LP 2-8 MHz Chebychev filter -% -% From "RF Circuit Design", Chris Bowick, Ch 3 - -1; - -function C = find_C(Cn, fc, R) - C = Cn/(2*pi*fc*R); -endfunction - -function L = find_L(Ln, fc, R) - L = R*Ln/(2*pi*fc); -endfunction - -% 3rd order HP filter, 1dB ripple Cheby, 3MHz cut off, >20dB down at -% 1MHz to nail strong AM broadcast signals, Table 3-7A. Use a Rs=50, -% Rl=50, so Rs/Rl = 1. Note we assume a or phantom load in between -% cascaded HP-LP sections of 50 ohms. - -L1 = find_L(1/2.216, 3E6, 50); -C1 = find_C(1/1.088, 3E6, 50); -L2 = find_L(1/2.216, 3E6, 50); - -printf("L1: %f uH C1: %f pF L2: %f uH\n", L1*1E6, C1*1E12, L2*1E6); - -% 3rd order LPF, 8MHz cut off so >30dB down at 21MHz, which aliases back to 7MHz -% with Fs=28MHz on RTLSDR (14 MHz Nyquist freq). Rs=50, Rl=50, Rs/Rl = 1 - -C2 = find_C(2.216, 9E6, 50); -L3 = find_L(1.088, 9E6, 50); -C3 = find_C(2.216, 9E6, 50); - -printf("C2: %f pF L3: %f uH C3: %f pF\n", C2*1E12, L3*1E6, C3*1E12); diff --git a/octave/rf_design.m b/octave/rf_design.m deleted file mode 100644 index eae79f6..0000000 --- a/octave/rf_design.m +++ /dev/null @@ -1,77 +0,0 @@ -% rfdesign.m -% -% David Rowe Nov 2015 -% -% Helper functions for RF Design - -1; - - -% convert a parallel R/X to a series R/X - -function Zs = zp_to_zs(Zp) - Xp = j*imag(Zp); Rp = real(Zp); - Zs = Xp*Rp/(Xp+Rp); -endfunction - - -% convert a series R/X to a parallel R/X - -function Zp = zs_to_zp(Zs) - Xs = imag(Zs); Rs = real(Zs); - Q = Xs/Rs; - Rp = (Q*Q+1)*Rs; - Xp = Rp/Q; - Zp = Rp + j*Xp; -endfunction - - -% Design a Z match network with a parallel and series reactance -% to match between a low and high resistance. Note Xp and Xs -% must be implemented as opposite sign, ie one a inductor, one -% a capacitor (your choice). -% -% /--Xs--+---\ -% | | | -% Rlow Xp Rhigh -% | | | -% \------+---/ -% - -function [Xs Xp] = z_match(Rlow, Rhigh) - assert(Rlow < Rhigh, "Rlow must be < Rhigh"); - Q = sqrt(Rhigh/Rlow -1); - Xs = Q*Rlow; - Xp = Rhigh/Q; -endfunction - - -% Design an air core inductor, Example 1-5 "RF Circuit Design" - -function Nturns = design_inductor(L_uH, diameter_mm) - Nturns = sqrt(29*L_uH/(0.394*(diameter_mm*0.1/2))); -endfunction - - -% Work out series resistance Rl of series resonant inductor. Connect -% tracking generator to spec-an input, the series LC to ground. V is -% the ref TG level (e.g. with perfect 50 ohm term) in volts, Vmin is the -% minimum at series res freq. -% -% /-50-+---+ -% | | | -% TG C 50 spec-an -% | | | -% | L | -% | | | -% | Rl | -% | | | -% \----+---/ - -function Rl = find_rl(V,Vmin) - % at series resonance effect of C and L goes away and we are left with - % parallel combination of Ls and spec-an 50 ohm input impedance - - Rp = Vmin*50/(2*V*(1-Vmin/(2*V))); - Rl = 1/(1/Rp - 1/50) -endfunction diff --git a/octave/rf_vhf_amp.m b/octave/rf_vhf_amp.m deleted file mode 100644 index 8c5186a..0000000 --- a/octave/rf_vhf_amp.m +++ /dev/null @@ -1,206 +0,0 @@ -% s_param_rf.m -% -% David Rowe Nov 2015 -% -% Working for small signal VHF amplifier design using -% S-param techniques from "RF Circuit Design" by Chris Bowick - -rfdesign; % library of helped functions - -more off; - -Ic = 0.014; - -% BRF92 VCE=5V Ic=5mA 100MHz - -if Ic == 0.005 - S11 = 0.727*exp(j*(-43)*pi/180); - S12 = 0.028*exp(j*(69.6)*pi/180); - S21 = 12.49*exp(j*(147)*pi/180); - S22 = 0.891*exp(j*(-16)*pi/180); -end - -% BRF92 VCE=10V Ic=14mA 100MHz - -if Ic == 0.02 - S11 = 0.548*exp(j*(-56.8)*pi/180); - S12 = 0.020*exp(j*(67.8)*pi/180); - S21 = 20.43*exp(j*(133.7)*pi/180); - S22 = 0.796*exp(j*(-18.5)*pi/180); -end - -% Stability - -Ds = S11*S22-S12*S21; -Knum = 1 + abs(Ds)^2 - abs(S11)^2 - abs(S22)^2; -Kden = 2*abs(S21)*abs(S12); -K = Knum/Kden % If > 1 unconditionally stable - % If < 1 panic -figure(1); -clf -scCreate; - -if K < 1 - C1 = S11 - Ds*conj(S22); - C2 = S22 - Ds*conj(S11); - rs1 = conj(C1)/(abs(S11)^2-abs(Ds)^2); % centre of input stability circle - ps1 = abs(S12*S21/(abs(S11)^2-abs(Ds)^2)); % radius of input stability circle - rs2 = conj(C2)/(abs(S22)^2-abs(Ds)^2); % centre of input stability circle - ps2 = abs(S12*S21/(abs(S22)^2-abs(Ds)^2)); % radius of input stability circle - - s(1,1)=S11; s(1,2)=S12; s(2,1)=S21; s(2,2)=S22; - plotStabilityCircles(s) -end - -% Gain circle - -D2 = abs(S22)^2-abs(Ds)^2; -C2 = S22 - Ds*conj(S11); -GdB = 20; Glin = 10^(GdB/10); % lets shoot for 20dB gain -G = Glin/(abs(S21)^2); -r0 = G*conj(C2)/(1+D2*G); % centre of gain circle -p0 = sqrt(1 - 2*K*abs(S12*S21)*G + (abs(S12*S21)^2)*(G^2))/(1+D2*G); % radius of gain circle - -scAddCircle(abs(r0),angle(r0)*180/pi,p0,'g') -printf("Green is the %3.1f dB constant gain circle for gammaL\n",GdB); - -% Note different design procedures for different operating points - -if Ic == 0.005 - % Choose a gammaL on the gain circle - - gammaL = 0.8 - 0.4*j; - - % Caclulate gammaS and make sure it's stable by visual inspection - % compared to stability circle. - - gammaS = conj(S11 + ((S12*S21*gammaL)/(1 - (gammaL*S22)))); -end - -if Ic == 0.014 - - % lets set zo (normalised Zo) based on Pout and get gammaL from that - - Pout = 0.01; - Irms = 0.002; - Zo = Pout/(Irms*Irms); - zo = Zo/50; - [magL,angleL] = ztog(zo); - gammaL = magL*exp(j*angleL*pi/180); - - % calculate gammaS - - gammaS = conj(S11 + ((S12*S21*gammaL)/(1 - (gammaL*S22)))); - -end - -[zo Zo] = gtoz(abs(gammaL), angle(gammaL)*180/pi,50); -[zi Zi] = gtoz(abs(gammaS), angle(gammaS)*180/pi,50); - -scAddPoint(zi); -scAddPoint(zo); - -% Transducer gain - -Gt_num = (abs(S21)^2)*(1-abs(gammaS)^2)*(1-abs(gammaL)^2); -Gt_den = abs((1-S11*gammaS)*(1-S22*gammaL) - S12*S21*gammaL*gammaS)^2; -Gt = Gt_num/Gt_den; - -if Ic == 0.005 - - % Lets design the z match for the input ------------------------------ - - % put input impedance in parallel form - - Zip = zs_to_zp(Zi); - - % first match real part of impedance - - Rs = 50; Rl = real(Zip); - [Xs Xp] = z_match(Rs,Rl); - - % Modify Xp so transistor input sees conjugate match to Zi - % Lets make Xp a capacitor, so negative sign - - Xp_match = -Xp - imag(Zip); - - % Now convert to real component values - - w = 2*pi*150E6; - Ls = Xs/w; diameter_mm = 6.25; - Ls_turns = design_inductor(Ls*1E6, diameter_mm); - Cp = 1/(w*(-Xp_match)); - - printf("Transducer gain: %3.1f dB\n", 10*log10(Gt)); - printf("Input: Zi = %3.1f + %3.1fj ohms\n", real(Zi), imag(Zi)); - printf(" In parallel form Rp = %3.1f Xp = %3.1fj ohms\n", real(Zip), imag(Zip)); - printf(" So for a conjugate match transistor input wants to see:\n Rp = %3.1f Xp = %3.1fj ohms\n", real(Zip), -imag(Zip)); - printf(" Rs = %3.1f to Rl = %3.1f ohm matching network Xs = %3.1fj Xp = %3.1fj\n", Rs, Rl, Xs, Xp); - printf(" with conj match to Zi Xs = %3.1fj Xp = %3.1fj\n", Xs, Xp_match); - printf(" matching components Ls = %5.3f uH Cp = %4.1f pF\n", Ls*1E6, Cp*1E12); - printf(" Ls can be made from %3.1f turns on a %4.2f mm diameter air core\n", Ls_turns, diameter_mm); - - % Now Z match for output ------------------------------------- - - Lo = -imag(Zo)/w; - Lo_turns = design_inductor(Lo*1E6, diameter_mm); - printf("Output: Zo = %3.1f + %3.1fj ohms\n", real(Zo), imag(Zo)); - printf(" So for a conjugate match transistor output wants to see:\n Rl = %3.1f Xl = %3.1fj ohms\n", real(Zo), -imag(Zo)); - printf(" Which is a series inductor Lo = %5.3f uH\n", Lo*1E6); - printf(" Lo can be made from %3.1f turns on a %4.2f mm diameter air core\n", Lo_turns, diameter_mm); -end - - -if Ic == 0.014 - printf("Transducer gain: %3.1f dB\n", 10*log10(Gt)); - - % Lets design the z match for the input ------------------------------ - - % put input impedance in parallel form - - Zip = zs_to_zp(Zi); - - % first match real part of impedance - - Rs = 50; Rl = real(Zip); - [Xs Xp] = z_match(Rl,Rs); - - % Lets make Xs a capacitir to block DC, so Xp is an inductor. - % Modify Xs so transistor input sees conjugate match to Zi. Xs is a - % capacitor, so reactance is negative - - Xs_match = -Xs - imag(Zip); - - % Now convert to real component values - - w = 2*pi*150E6; diameter_mm = 6.25; - Li = Xp/w; - Li_turns = design_inductor(Li*1E6, diameter_mm); - Ci = 1/(w*(-Xs_match)); - - printf("Input: Zi = %3.1f + %3.1fj ohms\n", real(Zi), imag(Zi)); - printf(" In parallel form Rp = %3.1f Xp = %3.1fj ohms\n", real(Zip), imag(Zip)); - printf(" So for a conjugate match transistor input wants to see:\n Rp = %3.1f Xp = %3.1fj ohms\n", real(Zip), -imag(Zip)); - printf(" Rs = %3.1f to Rl = %3.1f ohm matching network Xs = %3.1fj Xp = %3.1fj\n", Rs, Rl, Xs, Xp); - printf(" with Xs a capacitor, and Xp and inductor Xs = %3.1fj Xp = %3.1fj\n", -Xs, Xp); - printf(" With a conj match to Zi Xs = %3.1fj Xp = %3.1fj\n", Xs_match, Xp); - printf(" matching components Li = %5.3f uH Ci = %4.1f pF\n", Li*1E6, Ci*1E12); - printf(" Li can be made from %3.1f turns on a %4.2f mm diameter air core\n", Li_turns, diameter_mm); - - % Design output Z match ---------------------------------------------- - - Rs = real(Zo); Rl = 50; - [Xs Xp] = z_match(Rl,Rs); - - % Lets make XP an inductor so it can double as a RF choke, and Xp as - % a capacitor will give us a convenient DC block - - w = 2*pi*150E6; diameter_mm = 6.25; - Lo = Xp/w; Lo_turns = design_inductor(Lo*1E6, diameter_mm); - Co = 1/(w*Xs); - printf("Output: Zo = %3.1f + %3.1fj ohms\n", real(Zo), imag(Zo)); - printf(" matching network Xp = %3.1f X = %3.1f ohms\n", Xp, Xs); - printf(" which is parallel Lo = %5.3f uH and series Co = %4.1f pF\n", Lo*1E6, Co*1E12); - printf(" Lo can be made from %3.1f turns on a %4.2f mm diameter air core\n", Lo_turns, diameter_mm); -end - diff --git a/octave/rf_vhf_pa.m b/octave/rf_vhf_pa.m deleted file mode 100644 index 000c3fc..0000000 --- a/octave/rf_vhf_pa.m +++ /dev/null @@ -1,111 +0,0 @@ -% vhf_pa.m -% -% David Rowe Dec 2015 -% -% Working for 0.5W VHF PA - -rfdesign; - -% BFQ19 Vce=5V Ic=50mA. These are small signal S-params, -% which (according to "RF Circuit Design") are not valid. -% However I need to start somewhere. - -S11 = 0.324*exp(j*(-158.1)*pi/180); -S12 = 0.031*exp(j*(75.9)*pi/180); -S21 = 19.693*exp(j*(102.7)*pi/180); -S22 = 0.274*exp(j*(-74.6)*pi/180); - -% Lets check stability - -Ds = S11*S22-S12*S21; -Knum = 1 + abs(Ds)^2 - abs(S11)^2 - abs(S22)^2; -Kden = 2*abs(S21)*abs(S12); -K = Knum/Kden -figure(1); -clf -scCreate; - -if K < 1 - C1 = S11 - Ds*conj(S22); - C2 = S22 - Ds*conj(S11); - rs1 = conj(C1)/(abs(S11)^2-abs(Ds)^2); % centre of input stability circle - ps1 = abs(S12*S21/(abs(S11)^2-abs(Ds)^2)); % radius of input stability circle - rs2 = conj(C2)/(abs(S22)^2-abs(Ds)^2); % centre of input stability circle - ps2 = abs(S12*S21/(abs(S22)^2-abs(Ds)^2)); % radius of input stability circle - - s(1,1)=S11; s(1,2)=S12; s(2,1)=S21; s(2,2)=S22; - plotStabilityCircles(s) -end - - -% determine collector load Rl for our desired power output - -if 0 -P = 0.5; -Vcc = 5; -w = 2*pi*150E6; - -Rl = Vcc*Vcc/(2*P); -end -Rl = 10; - -% choose gammaL based on Rl - -zo = Rl/50; -[magL,angleL] = ztog(zo); -gammaL = magL*exp(j*angleL*pi/180); - -% calculate gammaS and Zi and plot - -gammaS = conj(S11 + ((S12*S21*gammaL)/(1 - (gammaL*S22)))); -[zi Zi] = gtoz(abs(gammaS), angle(gammaS)*180/pi,50); - -scAddPoint(zi); -scAddPoint(zo); - -% design Pi network for matching Rl to Ro, where Ro > Rl -% -% /---+-Xs1-Xs2-+---\ -% | | | | -% Rl Xp1 Xp2 Ro -% | | | | -% \---+---------+---/ -% -% highest impedance used to define Q of pi network and determine R, -% the "virtual" impedance at the centre of the network, whuch is smaller -% than Rl and Ro - -Ro = 50; -Q = 3; -R = Ro/(Q*Q+1); - -Xp2 = Ro/Q; -Xs2 = Q*R; - -Q1 = sqrt(Rl/R - 1); -Xp1 = Rl/Q1; -Xs1 = Q1*R; - -Cp1 = 1/(w*Xp1); -Cp2 = 1/(w*Xp2); -Ls = (Xs1+Xs2)/w; - -printf("Output Matching:\n"); -printf(" Rl = %3.1f Ro = %3.1f\n", Rl, Ro); -printf(" Q = %3.1f virtual R = %3.1f\n", Q, R); -printf(" Xp1 = %3.1f Xs1 = %3.1f Xs2 = %3.1f Xp2 = %3.1f\n", Xp1, Xs1, Xs2, Xp2); -printf(" Cp1 = %3.1f pF Ls = %3.1f nH Cp2 = %3.1f pF\n", Cp1*1E12, Ls*1E9, Cp2*1E12); - -% design input matching network between 50 ohms source and 10 ohms at base - -Rb = 10; Rs = 50; - -[Xs Xp] = z_match(Rb, Rs); - -Lp = Xp/w; -Cs = 1/(w*Xs); - -printf("Input Matching:\n"); -printf(" Xs = %3.1f Xp = %3.1f\n", Xs, Xp); -printf(" Lp = %3.1f nH Cs = %3.1f pF\n", Lp*1E9, Cs*1E12); - |
