定性使用 BJT 三极管¶
陈硕 2024/05
BJT 大信号 Ebers-Moll 模型
放大区
三极管的定性使用:$\newcommand{\li}[1]{{i_\mathrm{#1}}}$ $\newcommand{\ui}[1]{{I_\mathrm{#1}}}$ $\newcommand{\lv}[1]{{v_\mathrm{#1}}}$ $\newcommand{\uv}[1]{{V_\mathrm{#1}}}$ $\newcommand{\sm}[2]{{{#1}_\mathrm{#2}}}$
- $\uv{BE}\approx 0.7$V,因 $V_\mathrm{BE}$ 略微增加时,$I_\mathrm{C}$ 显著增大。
- $\ui{E}\approx \ui{C}$,因 $\beta\gg 1$
- 无须针对不同的 $\beta$ 调整。
放大区
定性分析:
Emitter follower 的主要功能是阻抗变换,相当于把负载电阻 $\sm{R}{E}$ 的阻值放大了 $\beta + 1$ 倍。
假设负载电阻 $\sm{R}{E}=1$kΩ,如果 $\uv{E}=1$V,那么 $\ui{E}=1$mA。直接驱动需要 1mA 电流,但是通过 emitter follower,借助三极管的电流放大作用(假设 $\beta=100$),输入端只需要提供 $\dfrac{\ui{E}}{1+\beta}\approx 10$μA电流就能驱动电阻 $\sm{R}{E}$,相当于驱动一个 100kΩ 的电阻。
如果要求 $\uv{E}=10$V,那么 $\ui{E}=10$mA。直接驱动需要 10mA 电流。通过 emitter follower,输入端只需要提供 $\dfrac{\ui{E}}{1+\beta}\approx 100$μA电流就能驱动电阻 $\sm{R}{E}$,还是相当于驱动一个 100kΩ 的电阻。
这其实正是晶体管(transistor)的本意:transistor = transfer + resistor,“传阻/跨阻 transresistance”器件。把输出端的电阻 $\sm{R}{E}$ 变换到输入端,变换的比例是 $\beta+1$,相当于把 $\sm{R}{E}$ 的阻值放大了 $\beta + 1$ 倍。这里把 1kΩ 的电阻变为了约 100kΩ 的电阻,驱动起来就容易得多了。(这里只作定性处理,暂时忽略 $r_\pi$ 和 $\sm{r}{o}$)
ng.circ("""
Vcc Vcc 0 10V
Vin b 0 DC 5V SINE(5 3 1k)
Q Vcc b e NPN
Re e 0 1000
.model NPN NPN(IS=5fA BF=200 VAF=140)
.options savecurrents
""")
print_op()
ERROR:ngspyce.sharedspice:Using SPARSE 1.3 as Direct Linear Solver
@q[ib] = 20.612 uA @q[ic] = 4.270 mA @re[i] = 4.290 mA b = 5.0000 V e = 4.2903 V vcc = 10.0000 V vcc#branch = -4.270 mA vin#branch = -20.612 uA
ERROR:ngspyce.sharedspice:Using SPARSE 1.3 as Direct Linear Solver
<matplotlib.legend.Legend at 0x7f4dbf4ace10>
ng.cmd('tran 1u 3m')
Ic = -1000 * ng.vectors()['vcc#branch']
Ve = ng.vectors()['e']
Vin = ng.vectors()['b']
time = ng.vectors()['time'] * 1e3
plt.plot(time, Vin, label='Vin')
plt.plot(time, Ve, label='Vout')
plt.xlabel("time (ms)")
plt.ylabel("Vout (V)")
plt.legend()
ERROR:ngspyce.sharedspice:Using SPARSE 1.3 as Direct Linear Solver
<matplotlib.legend.Legend at 0x7f4dbf3ff410>
ERROR:ngspyce.sharedspice:Using SPARSE 1.3 as Direct Linear Solver
<matplotlib.legend.Legend at 0x7f4dbe909650>
Linear regulator¶
ng.circ("""
Vcc Vcc 0 10V
Vref b 0 5.7V
Q Vcc b e NPN
Re e 0 1000
.model NPN NPN(IS=5fA BF=200 VAF=140)
.options savecurrents
""")
print_op()
@q[ib] = 24.072 uA @q[ic] = 4.962 mA @re[i] = 4.986 mA b = 5.7000 V e = 4.9863 V vcc = 10.0000 V vcc#branch = -4.962 mA vref#branch = -24.072 uA
ng.cmd('dc re 9 5000 1')
Re = ng.vector('res-sweep')
Vout = ng.vector('e')
fig,ax = plt.subplots()
plt.plot(Vout/Re, Vout, label='Vout')
plt.xlabel('Iout (A)')
plt.ylabel('Vout (V)')
plt.legend(loc='center')
ax2 = ax.twinx()
plt.plot(Vout/Re, 5.7 - Vout, 'orange', label='Vbe')
plt.ylabel('Vbe (V)')
plt.legend(loc='right')
<matplotlib.legend.Legend at 0x7f9bc8944050>
截止区 cut-off region¶
BE 结是单向导通,所以当 Vb < Ve 时,三极管会截止。
ng.circ("""
Vcc Vcc 0 4V
Vee 0 Vee 4V
Vin b 0 DC 0V SINE(0, 4, 1k)
Q1 Vcc b e NPN
Re e Vee 1000
Rl e 0 1000
.model NPN NPN (IS=5fA BF=200 VAF=130)
""")
ng.cmd('tran 10u 3m')
Vin = ng.vectors()['b']
Vout = ng.vectors()['e']
time = ng.vector('time')*1000
plt.plot(time, Vin, label='Vin')
plt.plot(time, Vout, label='Vout')
ERROR:ngspyce.sharedspice:Using SPARSE 1.3 as Direct Linear Solver
[<matplotlib.lines.Line2D at 0x7f4dbe98aa10>]
解决办法:有源负载
BE 结击穿¶
小信号 BJT 的 BE 节击穿电压 $\uv{EBO}$ 大约是 6~7 V,但是 SPICE 的 BJT 模型没有对此建模。
Vbe 抵消¶
可以看成 NPN 射随器和 PNP 射随器的前后配对使用,利用 NPN 和 PNP 的极性相反,将 Vbe 抵消。
ng.circ("""
V1 vcc 0 10V
Q1 0 vin b PNP
Q2 vcc b e NPN
R1 vcc b 10k
R2 e 0 1k
Vin vin 0 DC 5 SINE(5 3 1k)
.model NPN NPN (IS=5fA BF=200 VAF=130)
.model PNP PNP (IS=2fA BF=150 VAF=80)
""")
print_op()
ng.cmd('tran 10u 3m')
Vin = ng.vectors()['vin']
Vb = ng.vectors()['b']
Vout = ng.vectors()['e']
time = ng.vector('time')*1000
plt.plot(time, Vin, label='Vin')
#plt.plot(time, Vb, label='Vb')
plt.plot(time, Vout, label='Vout')
plt.ylabel('Vout (V)')
plt.xlabel('time (ms)')
plt.legend()
ERROR:ngspyce.sharedspice:Using SPARSE 1.3 as Direct Linear Solver ERROR:ngspyce.sharedspice:Using SPARSE 1.3 as Direct Linear Solver
b = 5.6719 V e = 4.9584 V v1#branch = -5.367 mA vcc = 10.0000 V vin = 5.0000 V vin#branch = 2.550 uA
<matplotlib.legend.Legend at 0x7ff4c10bad50>
plt.plot(Vin, 1e3*(Vout-Vin))
plt.xlabel('Vin (V)')
plt.ylabel('Vout - Vin (mV)')
Text(0, 0.5, 'Vout - Vin (mV)')
推挽输出 push-pull¶
可以看成 NPN 射随器和 PNP 射随器的上下配对使用。
ng.circ("""
Vcc Vcc 0 5V
Vee 0 Vee 5V
Vin b 0 DC 0V SINE(0, 2, 1k)
Q1 Vcc b e NPN
Q2 Vee b e PNP
R1 e 0 100
.model NPN NPN(IS=2fA BF=200 VAF=130)
.model PNP PNP(IS=5fA BF=80 VAF=50)
""")
ng.cmd('op')
print(ng.vectors())
ng.cmd('tran 10u 2m')
Vin = ng.vectors()['b']
Vout = ng.vectors()['e']
time = ng.vector('time')*1000
plt.plot(time, Vin, label='Vin')
plt.plot(time, Vout, label='Vout')
plt.xlabel('time (ms)')
plt.legend()
{'vcc#branch': array([-1.00040769e-11]), 'vee#branch': array([-5.0105e-12]), 'vin#branch': array([-2.99999944e-15]), 'e': array([-3.42307629e-13]), 'b': array([0.]), 'vee': array([-5.]), 'vcc': array([5.])}
<matplotlib.legend.Legend at 0x7f9bc852d090>
定量分析与 Sziklai Pair¶
输入阻抗:前面我们分析过,从输入端看进去,emitter follower 相当于把射级负载电阻 $\sm{R}{E}$ 放大了 $\beta + 1$ 倍,再加上三极管本身的输入阻抗 $r_\pi$,整个电路的输入阻抗 $\sm{R}{i}=r_\pi+(1+\beta)\sm{R}{E}$,其中 $r_\pi=\dfrac{\beta}{\sm{g}{m}}=\dfrac{\beta\uv{T}}{\ui{C}}$。如果 $\ui{C}=1$mA,那么 $\sm{g}{m}=\dfrac{\ui{C}}{\uv{T}}=\dfrac{1\mathrm{mA}}{26\mathrm{mV}}=\dfrac{1}{26\Omega}\approx38.5$mS。如果 $\beta=100$,$r_\pi=\dfrac{\beta}{\sm{g}{m}}=100\times 26=2600\Omega$,跟 $\sm{R}{i}$ 的第二项 $(1+\beta)\sm{R}{E}$ 比起来,$r_\pi$ 通常可忽略不计。
输出阻抗:
易见输出电流为 $\li{E}$。
假设输入电压不变,输出电流从 1mA 变化为 10mA,那么输出电压会略微降低 60mV,因为 $\uv{T}\ln 10\approx 26\times 2.3\approx 60$mV. 那么它的输出阻抗 $\sm{R}{o}=\dfrac{\Delta \uv{out}}{\Delta \ui{out}} = \dfrac{60}{9}=6.67$Ω.
假设输出电流从 10mA 增加到 100mA,那么输出电压会继续降低 60mV,这时它的输出阻抗变为 $\sm{R}{o}=\dfrac{\Delta \uv{out}}{\Delta \ui{out}} = \dfrac{60}{90}=0.667$Ω.
可以看出,射极跟随器的输出阻抗与它当前的 $\ui{E}$ 有关,一般教科书用 $\sm{r}{e}$ 表示,$\sm{r}{e}=\dfrac{\uv{T}}{\ui{E}}\approx \dfrac{1}{\sm{g}{m}}$。这个电阻通常较小,在欧姆级别。
由于 $\sm{r}{e} >0$,所以电压增益 $\sm{A}{v} < 1$。通常 $\sm{R}{E}\gg\sm{r}{e}$,那么 $\sm{A}{v} \approx 1$.
如何继续降低输出阻抗?可以用 Complementary Feedback Pair (互补反馈对管),也叫 Sziklai 对管。有的地方甚至把它算作 Darlington 管的一种。
Q1 是中小功率管,Q2 通常是大功率管,Q1 和 Q2 的极性互补。
Q1 的偏置电流由 Q2 提供($\ui{C1}\approx\dfrac{\uv{BE2}}{R_1} + \ui{B2}$),因此与 $\uv{BE2}$ 的变化成正比,而不是与输出电流成正比。而 $\uv{BE2}\propto \ln \ui{out}$,即输出电流增大 10 倍,$\uv{BE2}$ 增加 60mV,$\ui{C1}$ 增加大约 $\dfrac{60\mathrm{mV}}{R_1}$,那么 $\Delta \uv{BE1}\approx\ln \Delta \ui{C1}$。 这个过程中对电流取了两次对数。可见这个电路降低了输出阻抗,提高了输出的线性度。
假设 $\beta_2=50$, $R_1=68$Ω,现在 $\ui{C2}=50$mA,$\uv{BE2}=0.7$V,$\ui{C1}=\dfrac{\uv{BE2}}{R_1}+\ui{B2}=\dfrac{0.7}{68}+\dfrac{\ui{C2}}{\beta_2} =11.3$mA;当 $\ui{C2}$ 增加到 500mA,$\uv{BE2}=0.76$V,$\ui{C1}=\dfrac{\uv{BE2}}{R_1}+\ui{B2} = \dfrac{0.76}{68}+\dfrac{\ui{C2}}{\beta_2} = 21.2$mA,则 $\Delta \uv{BE1}\approx 16.4$mV
这比原来的单管 emitter follower $\Delta \uv{BE1}\approx 60$mV 好得多,输出阻抗从 $\dfrac{60}{450}=0.133$Ω 降到了 $\dfrac{16.4}{450}=0.0364$Ω。
电流源 current source¶
跟 emitter follower 相似的电路,如果我们要的是集电极电流,那就是个电流源。
要定量,用运放。
Current limit¶
ng.circ("""
V1 Vin 0 dc 5 pulse(0 15 0 1 1)
R1 Vin b 47k
Q1 c b e NPN
R2 e 0 56
Q2 b e 0 NPN
Rload Vin c 100
.model NPN NPN(IS=2fA BF=200 VAF=130)
""")
print_op()
ng.cmd('tran 1m 1')
Vb = ng.vectors()['b']
Ve = ng.vectors()['e']
Vin2 = ng.vectors()['vin']
Iload2 = -1000 * ng.vectors()['v1#branch']
fig, ax = plt.subplots()
plt.plot(Vin2, Iload2)
plt.xlabel("Vcc (V)")
plt.ylabel("I load (mA)")
print('range %.2f mA' % (Iload2[-1] - Iload2[0]))
ax2 = ax.twinx()
Vbe2 = Vb - Ve
# plt.plot(Vin2, Ve, 'orange', label='Vbe1')
plt.plot(Vin2, Vbe, 'orange', label='Vbe2')
plt.ylabel('Vbe (V)')
plt.legend()
ERROR:ngspyce.sharedspice:Note: v1: dc value used for op instead of transient time=0 value. ERROR:ngspyce.sharedspice:Note: v1: dc value used for op instead of transient time=0 value.
b = 1.3588 V c = 3.9315 V e = 0.6013 V v1#branch = -10.762 mA vin = 5.0000 V range 12.01 mA
<matplotlib.legend.Legend at 0x7f9bc7a93550>
fig, ax = plt.subplots()
start=int(4/15*1000)
plt.plot(Vin2[start:], Iload2[start:])
plt.xlabel("Vcc (V)")
plt.ylabel("I load (mA)")
print('range %.2f mA' % (Iload2[-1] - Iload2[0]))
ax2 = ax.twinx()
plt.plot(Vin2[start:], Vbe2[start:], 'orange', label='Vbe2')
plt.ylabel('Vbe (V)')
plt.legend(loc='lower right')
range 12.01 mA
<matplotlib.legend.Legend at 0x7f9bc7a83f10>
Drive Zener diode
Vbe 抵消¶
- Q1/Q2 是 Vbe 抵消型电流源,产生正比于 Vin 的电流
- Q3/Q4 是以 $\uv{BE3}$ 为基准的固定电流源,产生 0.4mA 电流
- Q5/Q6 是比例电流源,将前面两个电流相加之后再放大 10 倍,产生输出电流
校准:
- 先将 Vin 接地,调节 R3 使输出为 4mA
- 将 Vin 设为最大值,调节 R2 使输出为 20mA
Phase splitter¶
%%tikz -ct
\ctikzset{european resistors, diodes/fill=cyan!20, transistors/arrow pos=end, transistors/fill=cyan!20}
\draw (0, 0) node [npn, tr circle] (Q) {};
\draw (Q.C) to [R, l={$R_C$}, bipoles/length=1.2cm] ++(0, 2) node [vcc] {Vcc};
\draw (Q.C) to [short, *-o] ++ (0.7, 0) node [right] {Vout$-$};
\draw (Q.B) to [short, -o] ++ (-0.7, 0) node[below]{Vin};
\draw (Q.E) to [R, l_={$R_E$}, bipoles/length=1.2cm] ++(0, -2) node[tlground]{};
\draw (Q.E) to [short, *-o] ++ (0.7, 0) node [right] {Vout+};
ng.circ("""
Vcc Vcc 0 15V
Q1 c b e npn
Rc Vcc c 1k
Re e 0 1k
Vin b 0 DC 5 SINE(5 3 1k)
.model npn npn(IS=2fA BF=200 VAF=130)
""")
print_op()
ng.cmd('tran 1u 5m')
Vb = ng.vector('b')
Vc = ng.vector('c')
Ve = ng.vector('e')
time = ng.vector('time')
plt.plot(time, Vb, label='Vb')
plt.plot(time, Ve, label='Ve')
plt.plot(time, Vc, label='Vc')
plt.legend()
b = 5.0000 V c = 10.7534 V e = 4.2670 V vcc = 15.0000 V vcc#branch = -4.247 mA vin#branch = -20.333 uA
<matplotlib.legend.Legend at 0x7f9bc5f46350>
Common-emitter amplifiler with emitter degeneration¶