サイトマップ

回路の素101 008 アンプ:差動アンプ

回路の素101 008 アンプ:差動アンプ

差動信号を増幅できる

回路図作成

  • 基本的な構成

ゲインは  A_v = 1 + \frac{R_2}{R_1}
ただし  \frac{R_2}{R_1} =\frac{R_4}{R_3} とする

応答性確認

シミュレーションを tranモード(デフォルト) で実行し、応答を見る

  • 差動信号として、逆位相の信号を入れた場合
  • 同相信号として、同位相/同レベルの信号を入れた場合
  • オフセット電圧(VR)を入れた場合
import matplotlib.pyplot as plt
import numpy as np

from PyLTSpice import SimCommander

fname = 'PrimaryCircuit1-008'
LTC = SimCommander(fname + '.asc')
!more +1 PrimaryCircuit1-008.net
V2 +Vcc 0 5
RLoad Vout 0 10k
V3 -Vcc 0 -5
XU1 N002 N001 +Vcc -Vcc Vout AD8676
R1 N001 Vin- 10k
R2 Vout N001 100k
R3 N002 Vin+ 10k
R4 VR N002 100k
V4 VR 0 0
V1 Vin+ 0 SINE(0 0.1 1k) AC 1
V5 Vin- 0 SINE(0 0.1 1k 0 0 180)
.tran 0 5m 0 0.1u
;ac oct 40 1 10Meg
.lib AD8676.lib
.backanno
.end
infos_ = [
    ['diff mode', 'V5', 'V5 Vin- 0 SINE(0 0.1 1k 0 0 180)\n'],
    ['com mode',  'V5', 'V5 Vin- 0 SINE(0 0.1 1k)\n'],
    ['Vofs',      'V4', 'V4 VR 0 1\n'],
]

fname = 'PrimaryCircuit1-008'
for i, [name_, key, info_] in enumerate(infos_):
    LTC = SimCommander(fname + '.asc')
    
    # netlistの中身を編集する
    line_no = LTC.get_component_info(key)['line']
    LTC.netlist[line_no] = info_
    print(LTC.get_component_info(key))  # 確認
    
    # 編集したnetlistの情報でバッチ処理を実行する
    run_net_file = fname + '_%d.net' % i
    LTC.run(run_filename=run_net_file)
    LTC.wait_completion()
{'designator': 'V5', 'nodes': ' Vin- 0', 'value': 'SINE(0 0.1 1k 0 0 180)', 'line': 11}
{'designator': 'V5', 'nodes': ' Vin- 0', 'value': 'SINE(0 0.1 1k)', 'line': 11}
{'designator': 'V4', 'nodes': ' VR 0', 'value': '1', 'line': 9}
from PyLTSpice import RawRead

fig = plt.figure(figsize=(6, 3))
ax1 = fig.add_subplot(1, 1, 1)

fname = 'PrimaryCircuit1-008'
for i, [name_, key, info_] in enumerate(infos_):
    LTR = RawRead(fname + '_%d.raw' % i)
    x     = LTR.get_trace('time').get_time_axis(0)
    tmp1  = LTR.get_trace('V(vout)').get_wave(0)
    ax1.plot(x * 1000, tmp1, label=name_)

ax1.legend(); ax1.grid()
ax1.set_xlabel('[ms]'); ax1.set_ylabel('V$_{out}$[V]')

fig.tight_layout()

fig.savefig('PrimaryCircuit1-008_Graph1.png')

ゲインは10倍の設定で、入力は振幅0.1Vなので、出力は 0.1 x 2 x 10 = 2V振幅 になっている
同相信号の場合、打ち消しあって、ほぼ消えている
オフセット(VR)に1V入れると、そのまま出力に+1Vされる

周波数特性

周波数特性も確認する
Vin-側はGNDに落として、Vin+に入力して取得する

from PyLTSpice import SimCommander

fname = 'PrimaryCircuit1-008'
fname_tmp = '_ac'
LTC = SimCommander(fname + '.asc')

line_no = LTC._get_line_starting_with('.tran')
sim_cmd = LTC.netlist[line_no]
LTC.netlist[line_no] = sim_cmd.replace('.tran', ';tran')
line_no = LTC._get_line_starting_with(';ac')
sim_cmd = LTC.netlist[line_no]
LTC.netlist[line_no] = sim_cmd.replace(';ac', '.ac')
print(LTC.netlist[line_no], end='')  # 確認

line_no = LTC.get_component_info('V5')['line']
LTC.netlist[line_no] = 'V5 Vin- 0 0\n'
print(LTC.get_component_info('V5'))  # 確認

# 編集したnetlistの情報でバッチ処理を実行する
run_net_file = fname + fname_tmp + '.net'
LTC.run(run_filename=run_net_file)
LTC.wait_completion()
.ac oct 40 1 10Meg
{'designator': 'V5', 'nodes': ' Vin- 0', 'value': '0', 'line': 11}
True
from PyLTSpice import RawRead

fig = plt.figure(figsize=(6, 4))
ax1 = fig.add_subplot(2, 1, 1)
ax2 = fig.add_subplot(2, 1, 2, sharex=ax1)

fname = 'PrimaryCircuit1-008'
fname_tmp = '_ac'
LTR = RawRead(fname + fname_tmp + '.raw')

freq  = np.abs(LTR.get_trace('frequency').get_wave(0))
Vout  = LTR.get_trace("V(vout)").get_wave(0)
ax1.plot(freq, 20*np.log10(np.abs(Vout)))
ax2.plot(freq, np.angle(Vout) / np.pi * 180)

ax1.grid()
ax1.set_xlabel("[Hz]"); ax1.set_ylabel("Gain[dB]")
ax1.set_xscale('log')
ax1.set_ylim(15, 22)

ax2.grid()
ax2.set_xlabel("[Hz]"); ax2.set_ylabel("Phase[deg]")
ax2.set_xscale('log')

fig.tight_layout()

fig.savefig('PrimaryCircuit1-008_Graph2.png')

オペアンプの性能で特性は決まるが、今回の場合1MHzほどがカットオフ周波数になっている

参考文献

この記事は以下の書籍を参考にしましたが、
私の拙い知識で書いておりますので、誤り等ありましたらご指摘ください