Ce document montre comment utiliser un transistor bipolaire dans une simulation SPICE. On utilise ngspice. Les données produites sont importées dans python avec la fonction décrite dans Lecture des sorties SPICE avec Python.
La déclaration d'un transistor à jonction bipolaire (BJT) se fait avec la syntaxe suivante :
Qxxx NC NB NE MODELE
Le nom du transistor doit commencer par Q. NC, NB et NE sont les nœuds du collecteur, de la base et de l'émetteur et MODELE le nom du modèle.
Les transistors bipolaires sont représentés dans SPICE par un modèle à 41 paramètres. Voir bwrcs.eecs.berkeley.edu/Classes/IcBook/SPICE/ pour la définition de ces paramètres. Si aucun nom de modèle n'est précisé, les paramètres par défaut s'appliquent. Il est préférable d'utiliser un jeu de paramètres correspondant précisément au transistor que l'on veut simuler. Les fabriquants de composants fournissent des modèles SPICE pour les composants les plus utilisés. Une liste de liens est consultable sur www.youspice.com.
Voici par exemple un modèle du transistor 2N2222A fourni par ON semiconductor :
************************************** * 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
Pour comprendre l'influence des différents paramètres, nous pouvons partir de ce modèle, simuler un circuit simple avec ce transistor, et faire varier quelques paramètres importants.
La caractéristique statique (DC) d'un transistor bipolaire NPN est obtenue avec le circuit suivant :
Figure pleine pageVoici la définition SPICE de ce circuit :
.INCLUDE modeles.cir Ib 1 0 DC 0 Vce 2 0 DC 0 Q 2 1 0 2n2222a
La commande .INCLUDE permet d'inclure le fichier dans lequel se trouve la définition du modèle 2n2222a.
On commence par tracer la courbe ib=f(Vbe) pour Vce=1 V et Vce=0 V. La commande DC permet de faire un balayage des valeurs appliquées par une source de tension ou de courant. Sa syntaxe est :
DC SRC START STOP INCREMENT
On fait varier ici le courant de base délivré par la source de courant.
.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()Figure pleine page
On s'intéresse à présent aux courbes ic=f(Vce) obtenues pour différents courants de base.
La commande .DC permet de faire varier à la fois le courant de base et la tension base-émetteur.
.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
Le tableau de valeurs exportées comporte toutes les tensions Vce et les courants ic correspondants. Le courant de base n'apparait pas explicitement dans le tableau. Comme on connait le nombre de points par courbe, on peut séparer les différentes courbes après l'importation du tableau :
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()Figure pleine page
La caractéristique dynamique en fonctionnement linéaire est obtenue en fixant un point de fonctionnement (DC) et en faisant varier le courant de base d'une très faible amplitude (AC). La tension collecteur-émetteur est choisie de manière à être dans le domaine de fonctionnement linéaire (2 volts).
La commande AC permet d'effectuer une analyse fréquentielle en utilisant la source déclarée avec l'option AC. Sa syntaxe est :
AC DEC NB_POINT FSTART FSTOP
où DEC indique qu'il faut NB_POINTS par décade. FSTART et FSTOP sont les fréquences de début et de fin.
.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
Voici le tracé du diagramme de Bode du gain en courant ic/ib en dynamique :
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()Figure pleine page
On voit ainsi que ce transistor peut être utilisé dans un montage d'amplification de signaux seulement en dessous de 1 mégahertz. Au delà de cette fréquence, le gain décroît de 20 décibels par décade.
La commutation consiste à passer de la zone de blocage à la zone de saturation. Voici le montage le plus simple permettant d'obtenir une commutation :
Figure pleine pageSi on fixe V1=5 , le courant de collecteur et la tension collecteur-émetteur vérifient l'équation :
Lorsque le courant de base est nul, le transistor est bloqué : ic=0 et Vce=V1. Lorsque le courant de base est non nul, par exemple ib=100 μA, le transistor est saturé : la tension collecteur-émetteur est très faible (de l'ordre de 0.1 volts) et donc le courant de collecteur est approximativement :
En examinant la caractéristique ic=f(Vce) pour ib=100 μA, on voit qu'un courant de collecteur ic=10 mA convient pour la zone de saturation. On peut donc choisir
Pour obtenir une source pulsée, on doit utiliser la syntaxe suivante :
PULSE(min max delai temps_montée temps_descente largeur_impulsion periode)
Dans le cas présent, on choisit une impulsion périodique sur le courant de base, d'amplitude 100 μA et de largeur 5 μs, avec des temps de descente et de montée nuls.
L'analyse transitoire est obtenue avec la commande suivante :
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()Figure pleine page
On voit ainsi que le temps de commutation de ce transistor est de l'ordre de 2 μs.