Examples / TI op amp handbook / DC amplifiers
Simple non inverting
SBOA092B page 71, Simple Non-Inverting: EI on the + input, RO 90 kΩ from the output to the - input and RI 10 kΩ from there to ground.
E_O = (R_O + R_I) / R_I x E_I = 10 E_IThe 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_non_inverting.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”The figure gives both values, so nothing is chosen. The claim is a parameter,
a_v = 10, held to the parts by one constraint:
require(equals(self.a_v, over(total(self.r_out.resistance, self.r_in.resistance), self.r_in.resistance)))What the simulation found
Section titled “What the simulation found”out/simulation.txt, from the decks under
out/spice/:
| Run | Measured | Claimed |
|---|---|---|
gain, operating point, E_I = 1 V | 10 | 10 (a_v), holds |
gain, the - input | 1 V | 1 V, holds |
swing, E_O at E_I = 1 V in a sweep | 10 V | 10 (a_v), holds |
swing, highest E_O | 13.51 V | 13.5 V, holds |
swing, lowest E_O | -13.51 V | -13.5 V, holds |
Both inputs sit at E_I, which is why the page warns about the common-mode limit. The bench’s op amp has no such limit, so the sweep shows the limit it does have: the output stops at its ±13.5 V swing once E_I passes 1.35 V.
Running it
Section titled “Running it”fang check examples/ti_opamp_handbook/dc_amplifiers/simple_non_inverting/simple_non_inverting.pypython examples/regenerate.py ti_opamp_handbook/dc_amplifiers/simple_non_inverting # needs ngspiceThe whole program
Section titled “The whole program”"""The simple non-inverting amplifier, SBOA092B page 71.Show 12 more lines
E_O = (R_O + R_I) / R_I x E_I = 10 E_I
E_I goes straight to the + input, and R_O and R_I divide the output back tothe - input. The figure gives the values, 90 kOhm and 10 kOhm, so there isnothing to choose: the gain is 100k / 10k = 10.
The page warns that the input common-mode limit must be observed, becauseboth inputs follow E_I. The macro-model has no common-mode limit, so thebench shows the other limit it does have: the output swing, which a 1.35 Vinput already reaches."""
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 Parameter, System, kOhm, requirefrom fang.parts import Resistorfrom fang.rationale import Citesfrom fang.simulation import DCSweep, OperatingPoint
from handbook import ( Bench, Claim, Ground, OpAmp, Run, Terminal, equals, over, ratio, total,)
class SimpleNonInverting(System): """E_I on the + input, R_O and R_I dividing the output back to the - input."""
figure = Cites( "E_O = (R_O + R_I) / R_I E_I = 10 E_I; input common mode voltage limit must be observed", document="SBOA092B, Handbook of Operational Amplifier Applications", locator="page 71, Simple Non-Inverting", )
a_v = Parameter("1", default=10 * ratio, description="E_O / E_I")
e_in = Terminal() e_out = Terminal() r_in = Resistor(resistance=10 * kOhm) r_out = Resistor(resistance=90 * kOhm) amp = OpAmp() ground = Ground()
def architecture(self): self.e_in.probe >> self.amp.non_inverting.signal self.amp.inverting.signal >> self.r_in.p1 self.r_in.p2 >> self.ground.node self.amp.inverting.signal >> self.r_out.p1 self.r_out.p2 >> self.amp.output.signal self.amp.output.signal >> self.e_out.probe
def constraints(self): require( equals( self.a_v, over(total(self.r_out.resistance, self.r_in.resistance), self.r_in.resistance), ) )
BENCH = Bench( page=71, title="Simple Non-Inverting", runs=[ Run( "gain", OperatingPoint(), drive={"e_in": "DC 1"}, measure={ "gain": "v({e_out.1}) / v({e_in.1})", "e_minus": "v({amp.IN-})", }, claims=[ Claim("gain", "a_v", within=0.001), Claim( "e_minus", 1, within=0.001, unit="V", note="the - input follows E_I: both inputs sit at the input voltage, which is the common-mode limit the page warns of", ), ], ), Run( "swing", DCSweep(source="VDRIVE_e_in", start="-2", stop="2", step="0.01"), drive={"e_in": "DC 0"}, measure={ "e_out_top": "max v({e_out.1})", "e_out_bottom": "min v({e_out.1})", "gain_at_1v": "find v({e_out.1}) at=1", }, claims=[ Claim("gain_at_1v", "a_v", within=0.001, note="E_O at E_I = 1 V, so the gain"), Claim("e_out_top", 13.5, within=0.01, unit="V", note="the macro-model's swing, reached at E_I = 1.35 V; its clamp diode lets it pass by a few mV, hence 1%"), Claim("e_out_bottom", -13.5, within=0.01, unit="V"), ], note="A sweep of E_I from -2 V to 2 V. The output is linear at 10 E_I until it meets the +/-13.5 V swing.", ), ],)The files it writes
Section titled “The files it writes”The parts, then the nets and the pads on them.
GND1 Ground -R1 10 kOhm -R2 90 kOhm -TP1 Terminal -TP2 Terminal -U1 OpAmp -Net-(GND1-Pad1) GND1.1 R1.2Net-(R1-Pad1) R1.1 R2.1 U1.IN-Net-(R2-Pad2) R2.2 TP2.1 U1.OUTNet-(TP1-Pad1) TP1.1 U1.IN+Every check that ran, and every one left undecided.
1 checks, 0 failed, 0 undecidedWhat the elaborated graph contains, by entity kind.
1 block 6 component 12 connection 1 constraint 1 evidence 3 interface 10 pin 10 port 44 totalsnapshot sha256:40d61acb4945d07baebb05221009f5568432848799e5d6e394e66ae650c196f7All of it, including the KiCad netlist, is in
examples/ti_opamp_handbook/dc_amplifiers/simple_non_inverting/out/. Rebuild it with:
fang build examples/ti_opamp_handbook/dc_amplifiers/simple_non_inverting/simple_non_inverting.py