def f2(Re1, Ic1, Vo1, Vcc, bjt): Vbe1 = eee51.bjt_find_vbe(Ic1, Vcc - (Re1 * Ic1) - (Vcc/2), \ bjt['Is'], bjt['n'], bjt['VA']) Re = (Vcc - (Vo1 + Vbe1)) / Ic1 return Re - Re1
ib2.append(float(line.split()[5])) # convert to mV and mA ic_mA = eee51.scale_vec(ic, g51.milli) vbe_mV = eee51.scale_vec(vbe, g51.milli) bjt_beta = [a / b for a, b in zip(ic2, ib2)] # bjt parameters from our dc characterization bjt_Is = 6.924988420125876e-13 bjt_n = 1.2610858394025979 g51.update_bjt_VA(-15.550605626760145) g51.update_bjt_vce(specs['vce']) # calculate the vbe needed for vce = 2.5V reqd_vbe = eee51.bjt_find_vbe(specs['ic'], specs['vce'], \ bjt_Is, bjt_n, g51.bjt_VA) # generate the ic for the ideal bjt model # using our values for Is, n, and VA at vce = 2.5V ic_ideal = [eee51.ideal_bjt_transfer(v, bjt_Is, bjt_n) for v in vbe] ic_ideal_mA = eee51.scale_vec(ic_ideal, g51.milli) # define the plot parameters plt_cfg = { 'grid_linestyle': 'dotted', 'title': 'BJT 2N2222A Transfer Characteristics', 'xlabel': r'$V_{BE}$ [V]', 'ylabel': r'$I_C$ [mA]', 'legend_loc': 'upper left', 'add_legend': True,
# Let's calculate the resistor needed to set the # output of the pnp current mirror to 1mA at a 2.5V output specs = {'ic': 1e-3, 'vce': 2.5, 'vcc': 5.0} #def fvbe(vbe): # return vbe - eee51.bjt_find_vbe( \ # specs['ic'] * (1 + (vbe/abs(pnp_2n3906['VA']))) / \ # (1 + (specs['vce']/abs(pnp_2n3906['VA']))), \ # vbe, pnp_2n3906['Is'], \ # pnp_2n3906['n'], pnp_2n3906['VA']) # #vbe23 = optimize.fsolve(fvbe, 0.7) vbe23 = eee51.bjt_find_vbe( \ specs['ic'], \ specs['vce'], pnp_2n3906['Is'], \ pnp_2n3906['n'], pnp_2n3906['VA']) # since we want to vce2 = 2.5V, and vce3 = vbe3 = vbe2 approx 0.7, we can use # VA to derate the ic of Q2: # ic3 / ic2 = ( 1 + vce3/va ) / (1 + vce2/va) ic3 = specs['ic'] * (1 + (vbe23/abs(pnp_2n3906['VA']))) / \ (1 + (specs['vce']/abs(pnp_2n3906['VA']))) ib3 = ic3 / pnp_2n3906['beta_1mA'] ib2 = specs['ic'] / pnp_2n3906['beta_1mA'] iR = ic3 + ib3 + ib2 Rbias = (specs['vcc'] - vbe23) / iR
'swingpp': 3.0, 'vcc': 5.0 } itail = 2 * specs['ic1'] vout = ((specs['vcc'] - specs['vomin']) / 2) + specs['vomin'] Rload = (specs['vcc'] - specs['vomin']) / itail # common mode input range cmir = vout - (specs['swingpp'] / 2) - 0.2 - specs['vxmin'] # vicmax - vicmin vxbias = specs['vxmin'] + (cmir / 2) # bias in the middle of the cmir vbe34 = eee51.bjt_find_vbe( \ itail, \ vxbias, npn_2n3904['Is'], \ npn_2n3904['n'], npn_2n3904['VA']) ib3 = itail / npn_2n3904['beta_1mA'] ic4 = itail ib4 = ic4 / npn_2n3904['beta_1mA'] Re = [0, 50, 100] Rm = [( specs['vcc'] - vbe34 - (R * ic4) ) / ( ic4 + ib3 + ib4) \ for R in Re] vbe12 = eee51.bjt_find_vbe( \ specs['ic1'], \ vout - vxbias, npn_2n3904['Is'], \ npn_2n3904['n'], npn_2n3904['VA'])
'VA' : -6.567733723930889, 'beta_1mA' : 135.63663029082588 } # Let's calculate the resistor needed to set the # output of the pnp current mirror to 1mA specs = { 'ic' : 1e-3, 'out' : 2.5, 'vcc' : 5.0 } # calculate vbe5 vbe56 = eee51.bjt_find_vbe( \ specs['ic'], \ specs['out'], npn_2n3904['Is'], \ npn_2n3904['n'], npn_2n3904['VA']) # get the loading of stage 2 ib5 = specs['ic'] / npn_2n3904['beta_1mA'] # calculate vbe1 vbe14 = eee51.bjt_find_vbe( \ specs['ic'], \ vbe56, npn_2n3904['Is'], \ npn_2n3904['n'], npn_2n3904['VA']) # get the vec of q2 vce2 = specs['vcc'] - vbe14 # Q2 now has to provide the input current of the 2nd stage
def f1b(Vx, Ic1, Vo1, Vic, bjt): Vbe1 = eee51.bjt_find_vbe(Ic1, Vo1 - Vx, \ bjt['Is'], bjt['n'], bjt['VA']) Vxp = Vic - Vbe1 return Vxp - Vx
vce = Vbe + vbe5 vbe3 = bjt['n'] * g51.VT * np.log(Ic / \ (bjt['Is'] * ( 1 + (vce/abs(bjt['VA']))))) return vbe3 - Vbe Vcc = 5.0 Ic3 = 1e-3 f1_args = (pnp_2n3906, Ic3, Vcc) Vbe3 = optimize.root(f1, 0.6, args=f1_args).x[0] Ic5 = 2 * Ic3 / pnp_2n3906['beta_1mA'] Vce5 = Vcc - Vbe3 Vbe5 = eee51.bjt_find_vbe(Ic5, Vce5, \ pnp_2n3906['Is'], pnp_2n3906['n'], pnp_2n3906['VA']) Vce3 = Vbe3 + Vbe5 Vo1 = Vcc - Vce3 Ic1 = 1e-3 Vic = 1.8 def f1b(Vx, Ic1, Vo1, Vic, bjt): Vbe1 = eee51.bjt_find_vbe(Ic1, Vo1 - Vx, \ bjt['Is'], bjt['n'], bjt['VA']) Vxp = Vic - Vbe1 return Vxp - Vx