This document shows how to use a bipolar transistor in a SPICE simulation. We use ngspice. The produced data is imported into python with the function described in Reading SPICE outputs with Python.
2. Define model parameters
The declaration of a bipolar junction transistor (BJT) is done with the following syntax:
Qxxx NC NB NE MODELE
The transistor name must start with Q. NC, NB and NE are the collector, base and emitter nodes and MODEL the model name.
Bipolar transistors are represented in SPICE by a 41-parameter model.
If no model name is specified, the default settings apply. It is preferable to use a set of parameters corresponding precisely to the transistor to be simulated. Component manufacturers provide SPICE models for the most commonly used components.
Here is for example a model of the 2N2222A transistor supplied by
************************************** * Model Generated by MODPEX * *Copyright(c) Symmetry Design Systems* * All Rights Reserved * * UNPUBLISHED LICENSED SOFTWARE * * Contains Proprietary Information * * Which is The Property of * * SYMMETRY OR ITS LICENSORS * *Commercial Use or Resale Restricted * * by Symmetry License Agreement * ************************************** * Model generated on Feb 28, 13 * MODEL FORMAT: SPICE3 .MODEL 2n2222a npn +IS=3.88184e-14 BF=929.846 NF=1.10496 VAF=16.5003 +IKF=0.019539 ISE=1.0168e-11 NE=1.94752 BR=48.4545 +NR=1.07004 VAR=40.538 IKR=0.19539 ISC=1.0168e-11 +NC=4 RB=0.1 IRB=0.1 RBM=0.1 +RE=0.0001 RC=0.426673 XTB=0.1 XTI=1 +EG=1.05 CJE=2.23677e-11 VJE=0.582701 MJE=0.63466 +TF=4.06711e-10 XTF=3.92912 VTF=17712.6 ITF=0.4334 +CJC=2.23943e-11 VJC=0.576146 MJC=0.632796 XCJC=1 +FC=0.170253 CJS=0 VJS=0.75 MJS=0.5 +TR=1e-07 PTF=0 KF=0 AF=1
To understand the influence of the different parameters, we can start from this model, simulate a simple circuit with this transistor, and vary some important parameters.
3. Static characteristic
The static characteristic (DC) of an NPN bipolar transistor is obtained with the following circuit:
Here is the SPICE definition of this circuit:
.INCLUDE modeles.cir Ib 1 0 DC 0 Vce 2 0 DC 0 Q 2 1 0 2n2222a
The .INCLUDE command is used to include the file in which the definition of model 2n2222a is located.
We start by plotting the curve ib = f (Vbe) for Vce = 1 V and Vce = 0 V. The DC command is used to scan the values applied by a voltage or current source. Its syntax is:
DC SRC START STOP INCREMENT
The base current delivered by the current source is varied here. Transistor-1.cir
.INCLUDE modeles.cir Ib 0 1 DC 0 Vce 2 0 DC 1 Q 2 1 0 2n2222a .control DC Ib 0 100U 0.1U PRINT V(1) > export-1.txt .endc .end
.INCLUDE modeles.cir Ib 0 1 DC 0 Vce 2 0 DC 0 Q 2 1 0 2n2222a .control DC Ib 0 100U 0.1U PRINT V(1) > export-2.txt .endc .end
ngspice -b transistor-1.cir
ngspice -b transistor-2.cir
from lectureSpicePrint import lectureSpicePrint from matplotlib.pyplot import * data = lectureSpicePrint("export-1.txt") ib_1 = data["i-sweep"]*1e6 Vbe_1 = data["v(1)"] data = lectureSpicePrint("export-2.txt") ib_2 = data["i-sweep"]*1e6 Vbe_2 = data["v(1)"] figure(figsize=(5,5)) plot(Vbe_1,ib_1,label="Vce = 1 V") plot(Vbe_2,ib_2,label="Vce = 0 V") xlabel("Vbe (V)") ylabel("ib (muA)") axis([0,1,-10,100]) legend(loc="upper left") grid()
We are now interested in the curves ic = f (Vce) obtained for different base currents.
The .DC command is used to vary both the base current and the base-emitter voltage.transistor-3.cir
.INCLUDE modeles.cir Ib 0 1 DC 0 Vce 2 0 DC 0 Q 2 1 0 2n2222a .control DC Vce 0 5 0.05 Ib 0 100U 10U PRINT I(Vce) > export-3.txt .endc .end
ngspice -b transistor-3.cir
The table of exported values includes all the voltages Vce and the corresponding ic currents. The base current does not appear explicitly in the table. As we know the number of points per curve, we can separate the different curves after importing the table:
data = lectureSpicePrint("export-3.txt") np = 101 figure(figsize=(10,5)) i=0 for k in range(11): ib = 10.0*k Vce = data["i-sweep"][i:i+np] ic = -data["i(vce)"][i:i+np]*1e3 plot(Vce,ic,label="ib = %f muA"%ib) i += np xlabel("Vce (V)") ylabel("ic (mA)") axis([0,10,-5,30]) legend(loc="upper right") grid()
4. Dynamic characteristics
4.a. Linear operation
The dynamic characteristic in linear operation is obtained by setting an operating point (DC) and varying the base current by a very small amplitude (AC). The collector-emitter voltage is chosen so as to be in the linear operating range (2 volts).
The AC command is used to perform a frequency analysis using the source declared with the AC option. Its syntax is:
AC DEC NB_POINT FSTART FSTOP
where DEC indicates that NB_POINTS per decade is required. FSTART and FSTOP are the start and end frequencies. Transistor-4.cir
.INCLUDE modeles.cir Ib 0 1 DC 50U AC 1U Vce 2 0 DC 2 Q 2 1 0 2n2222a .control AC DEC 10 1K 1000MEG PRINT I(Vce) > export-4.txt .endc .end
ngspice -b transistor-4.cir
Here is the plot of the Bode diagram of the current gain ic / ib in dynamics:
import numpy data = lectureSpicePrint("export-4.txt") freq = data["frequency"] ic = data["i(vce)"] gdb = 20*numpy.log10(numpy.absolute(ic/1e-6)) phi = numpy.angle(ic) figure(figsize=(10,10)) subplot("211") plot(freq,gdb) xscale('symlog') xlabel('f (Hz)') ylabel('GdB') grid() subplot("212") plot(freq,phi) xscale('symlog') xlabel('f (Hz)') ylabel('phi (rad)') grid()
It can thus be seen that this transistor can be used in an assembly for amplifying signals only below 1 megahertz. Beyond this frequency, the gain decreases by 20 decibels per decade.
4.b. Switching operation
Switching consists of going from the blocking zone to the saturation zone. Here is the simplest assembly to obtain a switching:
If we set V1 = 5, the collector current and the collector-emitter voltage verify the equation: Vce + Rcic = V1 (1)
When the base current is zero, the transistor is blocked: ic = 0 and Vce = V1. When the base current is non-zero, for example ib = 100 μA, the transistor is saturated: the collector-emitter voltage is very low (of the order of 0.1 volts) and therefore the collector current is approximately: ic≃V1Rc (2)
Looking at the characteristic ic = f (Vce) for ib = 100 μA, we see that a collector current ic = 10 mA is suitable for the saturation zone. We can therefore choose Rc = V1ic = 500Ω (3)
To obtain a pulsed source, we must use the following syntax:
PULSE (min max delay rise_time descent_time pulse_width period)
In the present case, we choose a periodic pulse on the base current, amplitude 100 μA and width 5 μs, with zero fall and rise times.
The transient analysis is obtained with the following command:
TRAN pas_temps temps_final
.INCLUDE modeles.cir Ib 0 1 PULSE(0 100UA 1Us 0 0 5Us 20Us) Q 2 1 0 2n2222a Rc 2 3 500 V1 3 0 DC 5 .control TRAN 10Ns 40Us PRINT V(2) > export-5.txt .endc .end
ngspice -b transistor-5.cir
data = lectureSpicePrint("export-5.txt") t = data["time"]*1e6 v2 = data["v(2)"] figure(figsize=(10,5)) plot(t,v2) xlabel("t (mus)") ylabel("V2 (V)") grid()