Examples / TI op amp handbook / AC amplifiers
Simple AC amplifier
SBOA092B page 76, Simple Amplifier: EI through CI 1 µF and RI 10 kΩ into the summing point, RO 100 kΩ from the output back to it, and the + input on ground.
E_O = -R_O / R_I x E_I = -10 E_IZ_in = 10 kΩf_-3dB = 1 / (2 pi R_I C_I) = 16 HzThe circuit
Section titled “The circuit”The schematic is drawn by copperhead’s
drafting engine from this circuit’s netlist, with KiCad’s own library symbols,
and it opens in KiCad as figure/simple_ac_amplifier.kicad_sch.
The op amp is KiCad’s generic one, since the handbook’s are ideal, and each
terminal is a test point named as the program names it. KiCad reads back from
the sheet exactly the connections the circuit has; draw_figures.py refuses to write
one that does not.
The interconnect view is fang’s own projection. It names the parts as the program does, so it reads against the code below.
What the program says
Section titled “What the program says”Every value is drawn, so nothing is chosen. Three parameters hold the claims,
a_v = -10, z_in = 10 kΩ and f_low = 16 Hz; the last is held within 1%
of corner(R_I, C_I), 15.92 Hz, because the page rounds it.
What the simulation found
Section titled “What the simulation found”| Run | Measured | Claimed |
|---|---|---|
response, gain at 1 kHz | 9.999 | 10 (magnitude of a_v), holds |
response, Z_in at 1 kHz | 10 kΩ | 10 kΩ (z_in), holds |
response, low -3 dB point | 15.92 Hz | 16 Hz (f_low) ±1%, holds |
response, gain at 1 Hz | 0.627 | not a claim |
response, high -3 dB point | 909.1 kHz | not a claim |
dc, E_O with E_I = 1 V d.c. | 0 V | 0 V, holds |
C_I and R_I make one high-pass, so the corner is exactly 1/(2 pi R_I C_I). The upper corner is the op amp’s, 10 MHz over a noise gain of 11.
Running it
Section titled “Running it”fang check examples/ti_opamp_handbook/ac_amplifiers/simple_ac_amplifier/simple_ac_amplifier.pypython examples/regenerate.py ti_opamp_handbook/ac_amplifiers/simple_ac_amplifier # needs ngspiceThe whole program
Section titled “The whole program”"""The simple a.c. amplifier, SBOA092B page 76.Show 15 more lines
E_O = -R_O / R_I x E_I = -10 E_I Z_in = 10 kOhm f_-3dB = 1 / (2 pi R_I C_I) = 16 Hz
The inverting amplifier of page 54 with C_I in series with R_I. The summingpoint is a virtual ground, so C_I and R_I make a single high-pass whosecorner is the whole of the low-frequency roll-off, and above it the stage isthe inverting amplifier again. At d.c. C_I is open and the output sits at the+ input, ground.
The figure gives every value, so the program chooses nothing. 1/(2 pi 10k 1u)is 15.92 Hz, which the page rounds to 16, and the claim is held with thatrounding (`within`, 1%)."""
import sysfrom pathlib import Path
# The handbook's shared parts and bench live in the folder above the sections.sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
from fang.lang import Hz, Parameter, System, kOhm, require, uFfrom fang.parts import Capacitor, Resistorfrom fang.rationale import Citesfrom fang.simulation import ACSweep, OperatingPoint
from handbook import ( Bench, Claim, Ground, OpAmp, Run, Terminal, corner, equals, negative, over, ratio, within,)
class SimpleAcAmplifier(System): """E_I through C_I and R_I into the summing point, R_O back from the output."""
figure = Cites( "E_O = -R_O / R_I E_I = -10 E_I, Z_in = 10 kOhm; " "low frequency rolloff begins: f_-3dB = 1 / (2 pi R_I C_I) = 16 Hz", document="SBOA092B, Handbook of Operational Amplifier Applications", locator="page 76, Simple Amplifier", )
a_v = Parameter("1", default=-10 * ratio, description="E_O / E_I in the midband") z_in = Parameter("Ohm", default=10 * kOhm, description="what E_I sees in the midband") f_low = Parameter("Hz", default=16 * Hz, description="the low-frequency -3 dB point, as printed")
e_in = Terminal() e_out = Terminal() c_in = Capacitor(capacitance=1 * uF) r_in = Resistor(resistance=10 * kOhm) r_out = Resistor(resistance=100 * kOhm) amp = OpAmp() ground = Ground()
def architecture(self): self.e_in.probe >> self.c_in.p1 self.c_in.p2 >> self.r_in.p1 self.r_in.p2 >> self.amp.inverting.signal self.amp.inverting.signal >> self.r_out.p1 self.r_out.p2 >> self.amp.output.signal self.amp.output.signal >> self.e_out.probe self.amp.non_inverting.signal >> self.ground.node
def constraints(self): require(equals(self.a_v, negative(over(self.r_out.resistance, self.r_in.resistance)))) require(equals(self.z_in, self.r_in.resistance)) # 15.92 Hz, printed as 16. require(within(self.f_low, corner(self.r_in.resistance, self.c_in.capacitance), 0.01))
BENCH = Bench( page=76, title="Simple Amplifier", runs=[ Run( "response", ACSweep(points=40, start="0.1", stop="10meg"), drive={"e_in": "DC 0 AC 1"}, measure={ "gain_1k": "find vm({e_out.1}) at=1k", "i_in_1k": "find i(vdrive_e_in) at=1k", "z_in": "-1 / i_in_1k", "f_3db": "when vdb({e_out.1})=16.9897 cross=1", "gain_1hz": "find vm({e_out.1}) at=1", "f_high": "when vdb({e_out.1})=16.9897 cross=2", }, claims=[ Claim("gain_1k", 10, within=0.001, note="the magnitude of -10"), Claim( "z_in", "z_in", within=0.001, unit="Ohm", note=( "the 1 V drive over the in-phase part of its current at " "1 kHz, where C_I is 159 Ohm against 10 kOhm and moves " "it by 0.03%" ), ), Claim( "f_3db", "f_low", within=0.01, unit="Hz", note="1/(2 pi R_I C_I) is 15.92 Hz; the handbook prints 16", ), ], units={"f_high": "Hz", "i_in_1k": "A"}, note=( "The -3 dB points are where the gain falls to 20 dB - 3.01 dB. " "The upper one is not a handbook claim: it is the op amp's " "10 MHz over a noise gain of 11. At 1 Hz, a decade and more " "below the corner, the gain falls 20 dB per decade." ), ), Run( "dc", OperatingPoint(), drive={"e_in": "DC 1"}, measure={"e_out": "v({e_out.1})"}, claims=[ Claim( "e_out", 0, within=1e-6, absolute=True, unit="V", note="C_I blocks the 1 V: at d.c. the stage follows its + input, ground", ) ], ), ],)The files it writes
Section titled “The files it writes”The parts, then the nets and the pads on them.
C1 1 uF -GND1 Ground -R1 10 kOhm -R2 100 kOhm -TP1 Terminal -TP2 Terminal -U1 OpAmp -Net-(C1-Pad1) C1.1 TP1.1Net-(C1-Pad2) C1.2 R1.1Net-(GND1-Pad1) GND1.1 U1.IN+Net-(R1-Pad2) R1.2 R2.1 U1.IN-Net-(R2-Pad2) R2.2 TP2.1 U1.OUTEvery check that ran, and every one left undecided.
3 checks, 0 failed, 0 undecidedWhat the elaborated graph contains, by entity kind.
1 block 7 component 14 connection 3 constraint 1 evidence 3 interface 12 pin 12 port 53 totalsnapshot sha256:e23c9a99939576a0d1410c4254158dfac432febd2fb99c1ae7d40045b7622aabAll of it, including the KiCad netlist, is in
examples/ti_opamp_handbook/ac_amplifiers/simple_ac_amplifier/out/. Rebuild it with:
fang build examples/ti_opamp_handbook/ac_amplifiers/simple_ac_amplifier/simple_ac_amplifier.py