発振回路の理論 — 正帰還による信号生成の原理

ラジオのチューナーを回すと、さまざまな放送局の電波を受信できます。しかし、そもそも放送局はどうやって特定の周波数の電波を作り出しているのでしょうか? また、私たちが毎日使うスマートフォンやコンピュータの中では、数GHzもの高速なクロック信号がすべてのデジタル動作のタイミングを制御しています。これらの「特定の周波数の信号を自発的に生成する」回路が発振回路(オシレータ)です。

発振回路は、無線通信の搬送波生成(FMラジオからWi-Fiまで)、デジタル回路のクロック生成、周波数シンセサイザ、計測器の基準信号源、さらにはGPSの時刻同期まで、あらゆる電子システムの心臓部として機能しています。増幅回路が「外部からの入力を大きくする」装置であるのに対し、発振回路は「入力なしに自力で信号を生み出す」という本質的に異なる機能を持つ、エレクトロニクスの根幹をなす回路です。

本記事の内容

  • バルクハウゼンの発振条件の導出と物理的意味
  • LC発振器(コルピッツ発振器、ハートレー発振器)の回路と発振周波数
  • RC発振器(ウィーンブリッジ発振器)の動作原理
  • 水晶発振器の原理と高安定発振
  • VCO(電圧制御発振器)の概要
  • Pythonによる発振条件の解析とLC発振器のシミュレーション

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

発振の基本原理

発振はどうやって始まるのか

マイクとスピーカーを向かい合わせにすると、「キーン」というハウリング音が鳴ります。小さな音をマイクが拾い、アンプで増幅してスピーカーから出し、その音をまたマイクが拾う — このループが繰り返されるたびに音はどんどん大きくなります。これが正帰還による発振の直感的な姿です。

電子回路での発振も本質は同じです。増幅器の出力の一部を入力に戻し(帰還)、その帰還が入力を強める方向(正帰還)に作用すれば、信号は自己増殖的に成長します。最終的に、増幅器の非線形性(飽和)によって振幅が制限され、一定振幅の持続的な発振が得られます。

しかし、「信号が自己増殖する」だけでは不十分です。もし全ての周波数で信号が増幅されるなら、出力はカオス的な雑音になってしまいます。きれいな正弦波を発振させるには、特定の1つの周波数だけが正帰還の条件を満たすように回路を設計する必要があります。

バルクハウゼンの発振条件

帰還増幅回路の閉ループ利得は次の式で与えられました。

$$ A_f = \frac{A}{1 – A\beta} $$

ここで前の記事と符号の約束が変わっていることに注意してください。負帰還では $A_f = A/(1 + A\beta)$ と書きましたが、正帰還では帰還信号が入力を強めるため $A_f = A/(1 – A\beta)$ となります($\beta$ の符号が逆)。

$A\beta = 1$ のとき分母がゼロになり、閉ループ利得は無限大になります。これは「入力がゼロでも有限の出力が存在しうる」ことを意味し、自己持続的な発振状態に対応します。

一般に $A$ と $\beta$ は複素数(周波数依存)なので、$A\beta = 1$ は次の2つの条件に分解されます。

$$ |A\beta| = 1 \quad (\text{ループ利得条件}) $$

$$ \angle A\beta = 0° \quad (\text{位相条件、$360°$ の整数倍も可}) $$

これがバルクハウゼンの発振条件です。

ループ利得条件 $|A\beta| = 1$ は、信号がループを一巡したときに振幅が変わらないことを意味します。$|A\beta| > 1$ なら信号は成長し、$|A\beta| < 1$ なら減衰します。

位相条件 $\angle A\beta = 0°$ は、帰還信号が入力信号と同相(強め合う方向)であることを意味します。この条件を満たす周波数が発振周波数 $f_0$ になります。

実際の発振器では、起動時には $|A\beta| > 1$ で信号が成長し、振幅が増大するにつれて増幅器の非線形性によって実効的な $|A\beta|$ が低下し、最終的に $|A\beta| = 1$ で安定な発振に落ち着きます。

バルクハウゼン条件は、発振回路を設計するための一般的な指針を与えてくれます。次は、この条件を具体的な回路で実現する方法を見ていきましょう。最も歴史的かつ基本的なLC発振器から始めます。

LC発振器

LC共振の復習

LC発振器を理解するために、まずLC直列/並列共振回路の基本を確認しましょう。

インダクタンス $L$ とキャパシタンス $C$ からなる理想的なLC回路では、コンデンサに蓄えられた電気エネルギーとインダクタに蓄えられた磁気エネルギーが交互に変換され、永続的な振動が生じます。これは、ばね(弾性エネルギー)とおもり(運動エネルギー)の間でエネルギーが行き来する力学的振動と全く同じ物理です。

共振周波数は次の式で与えられます。

$$ f_0 = \frac{1}{2\pi\sqrt{LC}} $$

角周波数では $\omega_0 = 1/\sqrt{LC}$ です。この周波数で、インダクタのインピーダンス $j\omega L$ とキャパシタのインピーダンス $1/(j\omega C)$ が大きさが等しく符号が逆になり、互いに打ち消し合います。

実際の回路には抵抗成分(損失)があるため、エネルギーは徐々に散逸し、振動は減衰します。発振を持続させるには、増幅器が毎サイクルで失われるエネルギーを補給する必要があります。バルクハウゼン条件の $|A\beta| = 1$ は、まさにこの「エネルギーの補給量 = 損失量」の平衡を表しています。

コルピッツ発振器

コルピッツ発振器は、2つのコンデンサ $C_1$, $C_2$ と1つのインダクタ $L$ で帰還回路を構成するLC発振器です。

回路構成を説明します。トランジスタ(エミッタ接地またはソース接地)の出力がLC共振回路に接続されます。$C_1$ はトランジスタのベース-エミッタ間(またはゲート-ソース間)に、$C_2$ はコレクタ-エミッタ間(またはドレイン-ソース間)に配置されます。$L$ は $C_1$ と $C_2$ の直列接続に並列に入ります。

発振周波数の導出: LC共振回路の共振周波数が発振周波数を決定します。$C_1$ と $C_2$ の直列合成容量は次のとおりです。

$$ C_{total} = \frac{C_1 C_2}{C_1 + C_2} $$

したがって、発振周波数は次のようになります。

$$ f_0 = \frac{1}{2\pi\sqrt{L \cdot \frac{C_1 C_2}{C_1 + C_2}}} $$

発振条件の導出: 帰還回路の帰還率 $\beta$ は、$C_1$ と $C_2$ による容量分圧で決まります。共振周波数では、コンデンサのインピーダンスは虚数(リアクタンス)ですが、分圧比は次のように実数になります。

$$ \beta = \frac{v_{in}}{v_{out}} = \frac{C_2}{C_1} $$

ここで、容量が大きいほどインピーダンスが小さいことに注意してください。$C_2$ の両端の電圧のほうが小さく(インピーダンスが大きい $C_1$ のほうが電圧が大きい)、帰還率は $C_2/C_1$ になります。

バルクハウゼンの発振条件 $|A\beta| \geq 1$ から、増幅器に必要な最小利得は次のようになります。

$$ |A| \geq \frac{1}{\beta} = \frac{C_1}{C_2} $$

例えば $C_1 = 100 \, \text{pF}$, $C_2 = 10 \, \text{pF}$ の場合、$|A| \geq 10$ が必要です。

ハートレー発振器

ハートレー発振器は、コルピッツ発振器の「双対」ともいえる回路で、2つのインダクタ $L_1$, $L_2$ と1つのコンデンサ $C$ で帰還回路を構成します。

コルピッツがコンデンサの分圧で帰還率を決めるのに対し、ハートレーはインダクタの分圧で帰還率を決めます。

発振周波数: $L_1$ と $L_2$ の直列合成インダクタンスと $C$ の共振周波数です。

$$ f_0 = \frac{1}{2\pi\sqrt{(L_1 + L_2) C}} $$

ただし、$L_1$ と $L_2$ の間に相互インダクタンス $M$ がある場合は次のようになります。

$$ f_0 = \frac{1}{2\pi\sqrt{(L_1 + L_2 + 2M) C}} $$

帰還率: インダクタの分圧比で決まります。

$$ \beta = \frac{L_1}{L_2} $$

発振条件:

$$ |A| \geq \frac{L_2}{L_1} $$

コルピッツとハートレーの比較

特性 コルピッツ ハートレー
帰還素子 $C_1$, $C_2$(2つのコンデンサ) $L_1$, $L_2$(2つのインダクタ)
発振周波数 $1/(2\pi\sqrt{L \cdot C_1 C_2/(C_1+C_2)})$ $1/(2\pi\sqrt{(L_1+L_2)C})$
帰還率 $C_2/C_1$ $L_1/L_2$
周波数可変 バリキャップで $C$ を変える コアの透磁率を変える
高調波 少ない(コンデンサが高周波をバイパス) やや多い
高周波適性 良好(GHz帯まで) 中程度(低周波寄り)

一般に、高周波回路ではコルピッツ型が好まれます。コンデンサは寄生インダクタンスが小さく、高周波でも理想に近い動作をするためです。

LC発振器は高周波で優れた性能を発揮しますが、数Hz〜数百kHzの低い周波数では、必要なインダクタンスやキャパシタンスの値が非常に大きくなり実用的ではありません。次は、低周波用の発振器であるRC発振器を見ていきましょう。

RC発振器 — ウィーンブリッジ発振器

なぜRC発振器が必要か

低周波(可聴域: 20 Hz〜20 kHz)の正弦波を発振させたい場合、LC発振器では非現実的なサイズのコイルが必要になります。例えば、$f_0 = 1 \, \text{kHz}$, $C = 10 \, \text{nF}$ の場合、$L = 1/(4\pi^2 f_0^2 C) \approx 2.5 \, \text{H}$ という巨大なインダクタが必要です。

RC発振器はインダクタを使わず、抵抗とコンデンサだけで発振回路を構成します。最も実用的で広く使われているのがウィーンブリッジ発振器です。

ウィーンブリッジ回路の構成

ウィーンブリッジ発振器は、正帰還と負帰還を同時に使う巧みな構成です。オペアンプの非反転入力に正帰還(周波数選択性のあるRC回路網)を、反転入力に負帰還(抵抗分圧による利得設定)を接続します。

正帰還回路(ウィーンブリッジ): 抵抗 $R$ とコンデンサ $C$ の直列接続と並列接続を組み合わせた回路です。出力からこのRC回路網を通じて非反転入力に帰還します。

直列インピーダンスは $Z_1 = R + 1/(j\omega C)$、並列インピーダンスは $Z_2 = R \| (1/(j\omega C)) = R/(1 + j\omega RC)$ です。

帰還率(伝達関数)は次のように求まります。

$$ \beta(j\omega) = \frac{Z_2}{Z_1 + Z_2} $$

$Z_1$ と $Z_2$ を代入して整理しましょう。

$$ \beta(j\omega) = \frac{R/(1+j\omega RC)}{R + 1/(j\omega C) + R/(1+j\omega RC)} $$

分子分母に $(1 + j\omega RC) \cdot j\omega C$ を掛けて整理すると、次のようになります。

$$ \beta(j\omega) = \frac{j\omega RC}{1 + 3j\omega RC + (j\omega RC)^2} $$

$s = j\omega RC$ と置くと、$\beta = s/(1 + 3s + s^2)$ です。

発振周波数: 位相条件 $\angle \beta = 0°$ を満たす周波数を求めます。$\beta$ の分子は純虚数($j\omega RC$)で位相は $+90°$ です。位相が $0°$ になるためには、分母も $+90°$ の位相を持つ必要があります。

分母 $1 + 3j\omega RC – \omega^2 R^2 C^2$ の実部をゼロに設定します。

$$ 1 – \omega^2 R^2 C^2 = 0 $$

$$ \omega_0 = \frac{1}{RC}, \quad f_0 = \frac{1}{2\pi RC} $$

このとき、分母は $3j\omega_0 RC = 3j$ となり、帰還率は次のようになります。

$$ \beta(j\omega_0) = \frac{j}{3j} = \frac{1}{3} $$

つまり、発振周波数ではウィーンブリッジ回路は位相シフトゼロ、減衰率 $1/3$ のフィルタとして動作します。

発振条件: $|A\beta| \geq 1$ から、増幅器に必要な利得は次のようになります。

$$ |A| \geq \frac{1}{\beta} = 3 $$

負帰還回路(反転入力側の抵抗分圧 $R_f$, $R_1$)で非反転利得を $1 + R_f/R_1 = 3$ に設定します。

$$ \frac{R_f}{R_1} = 2 \quad \Rightarrow \quad R_f = 2R_1 $$

振幅安定化

$A = 3$ ちょうどでは、起動時の雑音が成長するのに時間がかかります。実用的には $A$ をわずかに3より大きく設定して起動を速くしますが、そのままでは振幅が増大し続けてクリッピング歪みが生じます。

これを解決するのが自動利得制御(AGC: Automatic Gain Control)です。代表的な手法は次のとおりです。

  1. ランプ(電球)AGC: $R_1$ の代わりに小さな白熱電球を使う。振幅が大きくなると電球の温度が上がり抵抗が増加、利得が低下して振幅が安定化される。ヒューレット・パッカードの最初の製品(HP200A)で使われた歴史的な手法
  2. FET AGC: FETのドレイン-ソース間抵抗を可変抵抗として使い、出力のピーク検出電圧でゲート電圧を制御する
  3. ダイオードリミッタ: 出力がある閾値を超えるとダイオードが導通し、帰還量が増えて利得が低下する

RC発振器は低周波の正弦波生成に適していますが、周波数安定度はLC発振器と同程度です。もっと桁違いに高い安定度が必要な場合 — 例えば通信用の基準周波数や精密計測 — には、水晶振動子を使った発振器が用いられます。

水晶発振器

水晶振動子の物理

水晶(石英, $\text{SiO}_2$)結晶は圧電効果を持ちます。機械的に圧力を加えると電圧が発生し、逆に電圧を加えると機械的に変形します。適切にカットされた水晶片に交流電圧を印加すると、機械的な共振が電気的な共振として現れます。

水晶振動子が特別なのは、そのQ値(Quality Factor)が桁違いに高いことです。LC回路のQ値がせいぜい100〜1,000程度であるのに対し、水晶振動子のQ値は数万〜数十万に達します。Q値が高いということは、共振のピークが鋭い(周波数選択性が高い)ことを意味し、発振周波数の安定度が格段に向上します。

Q値を具体的に感じてみましょう。Q = 100のLC回路で10 MHzの発振器を作ると、温度変化などで簡単に数kHzの周波数ドリフトが生じます。一方、Q = 100,000の水晶発振器なら、同様の擾乱に対して周波数ドリフトは数Hz程度に抑えられます。

水晶振動子の等価回路

水晶振動子の電気的な振る舞いは、次の等価回路で表されます。

直列共振回路($L_1$, $C_1$, $R_1$ の直列接続)に、並列容量 $C_0$ が並列に接続された構造です。

  • $L_1$: 運動インダクタンス(機械的な質量に相当)— 数mH〜数H
  • $C_1$: 運動キャパシタンス(機械的なバネに相当)— 数fF〜数十fF
  • $R_1$: 等価直列抵抗(ESR、機械的な損失に相当)— 数Ω〜数百Ω
  • $C_0$: 並列容量(電極間の静電容量)— 数pF

$L_1/C_1$ の比が非常に大きいことがQ値の高さの源です。Q値は次の式で表されます。

$$ Q = \frac{\omega_s L_1}{R_1} = \frac{1}{\omega_s C_1 R_1} $$

直列共振と並列共振

水晶振動子は2つの共振周波数を持ちます。

直列共振周波数 $f_s$: $L_1$ と $C_1$ の共振周波数で、インピーダンスが最小になります。

$$ f_s = \frac{1}{2\pi\sqrt{L_1 C_1}} $$

並列共振周波数 $f_p$: $C_1$ と $C_0$ の直列合成容量と $L_1$ の共振周波数で、インピーダンスが最大になります。

$$ f_p = f_s \sqrt{1 + \frac{C_1}{C_0}} $$

$C_1 \ll C_0$(典型的に $C_1/C_0 \approx 0.001$〜$0.01$)なので、$f_p$ は $f_s$ のわずかに上にあります。

$$ f_p \approx f_s \left(1 + \frac{C_1}{2C_0}\right) $$

$f_s$ と $f_p$ の間では、水晶振動子のインピーダンスは誘導性(インダクタのように振る舞う)です。多くの水晶発振回路は、この誘導性領域を利用して水晶を等価インダクタとして使い、外部のコンデンサとともにLC型発振回路を構成します。

水晶発振回路の構成

代表的な水晶発振回路としてピアース発振器があります。これは本質的にコルピッツ発振器の $L$ を水晶振動子で置き換えたものです。水晶が $f_s$ と $f_p$ の間で誘導性を示すことを利用しています。

CMOSインバータを増幅器として使うピアース型水晶発振器は、マイクロコントローラの外付けクロックとして最も一般的に使われている構成です。部品点数が少なく(水晶 + コンデンサ2個 + 抵抗1個)、安定した発振が得られます。

水晶発振器により、非常に高い周波数安定度が得られることがわかりました。しかし、通信システムでは多くの異なる周波数が必要です。固定周波数の水晶発振器だけでは対応できません。次は、発振周波数を電圧で制御できるVCOについて見ていきましょう。

VCO(電圧制御発振器)

VCOの基本概念

VCO(Voltage-Controlled Oscillator)は、入力する制御電圧によって発振周波数を変化させられる発振器です。PLLの構成要素として不可欠であり、周波数シンセサイザ、FM変調器、クロック生成回路などに広く使われています。

VCOの基本特性は、制御電圧 $V_{ctrl}$ と発振周波数 $f_{out}$ の関係で表されます。

$$ f_{out} = f_0 + K_{VCO} \cdot V_{ctrl} $$

ここで $f_0$ は自走周波数($V_{ctrl} = 0$ のときの周波数)、$K_{VCO}$ はVCO利得($\text{Hz/V}$)です。$K_{VCO}$ は周波数感度とも呼ばれ、制御電圧1Vあたりの周波数変化量を表します。

LC-VCO

LC-VCOは、LC発振器の共振回路にバリキャップダイオード(可変容量ダイオード)を挿入して構成します。バリキャップの容量 $C_v$ は逆バイアス電圧 $V_R$ に依存します。

$$ C_v(V_R) = \frac{C_{v0}}{(1 + V_R / V_\phi)^n} $$

$C_{v0}$ はゼロバイアス時の容量、$V_\phi$ は接合のビルトインポテンシャル(約0.7V)、$n$ は接合プロファイルに依存する指数(突合せ接合で $n = 0.5$、超急変接合で $n = 1$〜$2$)です。

制御電圧を変えると $C_v$ が変化し、それに伴って共振周波数 $f_0 = 1/(2\pi\sqrt{L C_{total}})$ が変化します。LC-VCOは高周波(GHz帯)で広く使われていますが、位相ノイズの低減がVCO設計の最大の課題です。

リングオシレータ

デジタル回路で広く使われるVCOとしてリングオシレータがあります。奇数個($N$個)のインバータをリング状に接続した構造で、各段の伝搬遅延 $t_d$ によって発振周波数が決まります。

$$ f_0 = \frac{1}{2 N t_d} $$

係数の $2$ は、信号がリングを2周して元の状態に戻るためです(1周で反転、2周で元に戻る)。

制御電圧でインバータの電源電流を変えると $t_d$ が変化し、周波数を制御できます。構造が単純でCMOSプロセスに容易に集積化できるため、PLL内蔵のマイコンやSoCで広く採用されています。

VCOの基本が理解できたところで、次はこれまでの理論をPythonで検証しましょう。

Pythonによる発振回路のシミュレーション

バルクハウゼン条件の可視化

まず、ウィーンブリッジ回路の帰還率の周波数特性を計算し、バルクハウゼン条件がどのように満たされるかを可視化します。

import numpy as np
import matplotlib.pyplot as plt

# ウィーンブリッジのパラメータ
R = 10e3     # 10 kΩ
C = 10e-9    # 10 nF
f0_theory = 1 / (2 * np.pi * R * C)

# 周波数範囲
freq = np.logspace(1, 6, 1000)
omega = 2 * np.pi * freq

# ウィーンブリッジの伝達関数 β(jω) = jωRC / (1 + 3jωRC - ω²R²C²)
s = 1j * omega * R * C
beta = s / (1 + 3 * s + s**2)

# 振幅と位相
beta_mag = np.abs(beta)
beta_phase = np.angle(beta, deg=True)

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8), sharex=True)

# 振幅特性
ax1.semilogx(freq, beta_mag, 'b-', linewidth=2)
ax1.axhline(y=1/3, color='r', linestyle='--', alpha=0.7, label='$|\\beta| = 1/3$')
ax1.axvline(x=f0_theory, color='g', linestyle=':', alpha=0.7,
            label=f'$f_0$ = {f0_theory:.0f} Hz')
ax1.set_ylabel(r'$|\beta(j\omega)|$', fontsize=12)
ax1.set_title('Wien Bridge Feedback Network - Frequency Response', fontsize=14)
ax1.legend(fontsize=11)
ax1.grid(True, which='both', alpha=0.3)

# 位相特性
ax2.semilogx(freq, beta_phase, 'b-', linewidth=2)
ax2.axhline(y=0, color='r', linestyle='--', alpha=0.7, label='Phase = 0°')
ax2.axvline(x=f0_theory, color='g', linestyle=':', alpha=0.7)
ax2.set_xlabel('Frequency [Hz]', fontsize=12)
ax2.set_ylabel('Phase [deg]', fontsize=12)
ax2.legend(fontsize=11)
ax2.grid(True, which='both', alpha=0.3)

plt.tight_layout()
plt.savefig('wien_bridge_response.png', dpi=150, bbox_inches='tight')
plt.show()

print(f"理論発振周波数: f0 = {f0_theory:.1f} Hz")
print(f"f0でのβの大きさ: |β(f0)| = {np.abs(beta[np.argmin(np.abs(freq-f0_theory))]):.4f}")
print(f"f0でのβの位相: ∠β(f0) = {np.angle(beta[np.argmin(np.abs(freq-f0_theory))], deg=True):.2f}°")
print(f"必要な増幅器利得: A ≥ 1/β = {1/np.max(beta_mag):.1f}")

上段の振幅特性から、ウィーンブリッジ回路は帯域通過フィルタのような特性を持ち、発振周波数 $f_0$ で振幅が最大値 $|\beta| = 1/3$ に達することがわかります。低周波ではコンデンサのインピーダンスが大きく信号が通過できず、高周波ではインピーダンスが小さくなり信号が分圧されて減衰します。$f_0$ でちょうどこのバランスが取れます。

下段の位相特性では、$f_0$ で位相がちょうど $0°$ を通過しています。$f_0$ より低い周波数では位相が正(進み)、高い周波数では負(遅れ)になっています。バルクハウゼンの位相条件 $\angle A\beta = 0°$ を満たすのは $f_0$ だけであり、これが発振周波数を一意に決定します。

増幅器の利得を $A = 3$ に設定すれば、$f_0$ でのみ $|A\beta| = 3 \times 1/3 = 1$ となり、発振条件が満たされます。他の周波数では $|\beta| < 1/3$ なので $|A\beta| < 1$ となり、発振しません。

コルピッツ発振器のループ利得解析

次に、コルピッツ発振器のループ利得を解析します。

import numpy as np
import matplotlib.pyplot as plt

# コルピッツ発振器のパラメータ
L = 10e-6       # 10 μH
C1 = 100e-12    # 100 pF
C2 = 10e-12     # 10 pF
R_loss = 5.0    # LC回路の損失抵抗 [Ω]

# 合成容量
C_total = C1 * C2 / (C1 + C2)
f0_theory = 1 / (2 * np.pi * np.sqrt(L * C_total))

# 帰還率
beta = C2 / C1

# 周波数範囲
freq = np.logspace(5, 9, 2000)
omega = 2 * np.pi * freq

# LC共振回路のインピーダンス(並列共振)
# Z_LC = jωL || (1/jωC1 + 1/jωC2) だが、簡略化モデルを使用
# 帰還回路の伝達関数
Z_L = 1j * omega * L
Z_C1 = 1 / (1j * omega * C1)
Z_C2 = 1 / (1j * omega * C2)

# フィードバックネットワークの伝達関数
# 出力(コレクタ)からLC回路を通じて入力(ベース)への伝達
# β(jω) = Z_C1 / (Z_L + Z_C1 + R_loss) (直列共振回路モデル)
beta_freq = Z_C1 / (Z_L + Z_C1 + Z_C2 + R_loss)

beta_mag = np.abs(beta_freq)
beta_phase = np.angle(beta_freq, deg=True)

fig, axes = plt.subplots(2, 2, figsize=(14, 10))

# β振幅
axes[0, 0].semilogx(freq / 1e6, beta_mag, 'b-', linewidth=2)
axes[0, 0].axvline(x=f0_theory / 1e6, color='g', linestyle=':', alpha=0.7,
                    label=f'$f_0$ = {f0_theory/1e6:.2f} MHz')
axes[0, 0].set_xlabel('Frequency [MHz]', fontsize=12)
axes[0, 0].set_ylabel(r'$|\beta|$', fontsize=12)
axes[0, 0].set_title('Colpitts: Feedback Magnitude', fontsize=13)
axes[0, 0].legend(fontsize=11)
axes[0, 0].grid(True, which='both', alpha=0.3)

# β位相
axes[0, 1].semilogx(freq / 1e6, beta_phase, 'b-', linewidth=2)
axes[0, 1].axhline(y=0, color='r', linestyle='--', alpha=0.7)
axes[0, 1].axvline(x=f0_theory / 1e6, color='g', linestyle=':', alpha=0.7)
axes[0, 1].set_xlabel('Frequency [MHz]', fontsize=12)
axes[0, 1].set_ylabel('Phase [deg]', fontsize=12)
axes[0, 1].set_title('Colpitts: Feedback Phase', fontsize=13)
axes[0, 1].grid(True, which='both', alpha=0.3)

# 発振周波数のC1/C2依存性
C2_range = np.linspace(1e-12, 200e-12, 200)
f0_list = []
beta_list = []
for c2 in C2_range:
    c_tot = C1 * c2 / (C1 + c2)
    f0_list.append(1 / (2 * np.pi * np.sqrt(L * c_tot)) / 1e6)
    beta_list.append(c2 / C1)

axes[1, 0].plot(C2_range * 1e12, f0_list, 'b-', linewidth=2)
axes[1, 0].axhline(y=f0_theory / 1e6, color='r', linestyle='--', alpha=0.5)
axes[1, 0].set_xlabel('$C_2$ [pF]', fontsize=12)
axes[1, 0].set_ylabel('$f_0$ [MHz]', fontsize=12)
axes[1, 0].set_title('Oscillation Frequency vs $C_2$', fontsize=13)
axes[1, 0].grid(True, alpha=0.3)

# 必要利得のC1/C2依存性
axes[1, 1].plot(C2_range * 1e12, [C1/c2 for c2 in C2_range], 'r-', linewidth=2)
axes[1, 1].set_xlabel('$C_2$ [pF]', fontsize=12)
axes[1, 1].set_ylabel('Minimum Gain $C_1/C_2$', fontsize=12)
axes[1, 1].set_title('Required Amplifier Gain vs $C_2$', fontsize=13)
axes[1, 1].grid(True, alpha=0.3)
axes[1, 1].set_ylim([0, 50])

plt.tight_layout()
plt.savefig('colpitts_analysis.png', dpi=150, bbox_inches='tight')
plt.show()

print(f"コルピッツ発振器:")
print(f"  L = {L*1e6:.0f} μH, C1 = {C1*1e12:.0f} pF, C2 = {C2*1e12:.0f} pF")
print(f"  合成容量: C_total = {C_total*1e12:.2f} pF")
print(f"  理論発振周波数: f0 = {f0_theory/1e6:.2f} MHz")
print(f"  帰還率: β = C2/C1 = {beta:.2f}")
print(f"  必要利得: A ≥ C1/C2 = {C1/C2:.0f}")

4つのグラフから、コルピッツ発振器の動作特性が読み取れます。

左上の帰還率の振幅特性を見ると、共振周波数付近で鋭いピークが生じています。これはLC共振回路の選択性を反映しており、Q値が高いほどピークが鋭くなります。

右上の位相特性では、共振周波数で位相が $0°$ を通過しています。共振よりも低い周波数ではインダクタのインピーダンスが小さく位相が進み、高い周波数ではコンデンサのインピーダンスが小さく位相が遅れるという物理的にも直感的な結果です。

左下のグラフは、$C_2$ を変化させたときの発振周波数の変化を示しています。$C_2$ を増やすと合成容量が増加し、発振周波数は低下します。$C_2$ が $C_1$ に近づくと合成容量は $C_1/2$ に近づき、周波数変化は緩やかになります。

右下のグラフは、$C_2$ に対する必要な最小利得を示しています。$C_2$ が小さいほど帰還率が小さくなるため、より大きな利得が必要です。しかし $C_2$ を大きくしすぎると帰還が強すぎて他の問題が生じるため、適切なバランスを取る必要があります。

LC発振器の過渡シミュレーション

最後に、発振の立ち上がり(起動)から定常状態への移行を時間領域でシミュレーションします。簡略化したモデルとして、帰還付きのバンデルポール型発振器を使います。

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

# バンデルポール型発振器モデル
# LC発振器の振幅制限を非線形抵抗でモデル化
# d²v/dt² - μ(1 - v²)dv/dt + ω₀²v = 0
# μ > 0: 正帰還(小振幅)+ 非線形制限(大振幅)

def vanderpol(y, t, mu, omega0):
    v, dvdt = y
    d2vdt2 = mu * (1 - v**2) * dvdt - omega0**2 * v
    return [dvdt, d2vdt2]

# パラメータ
f0 = 1e6  # 1 MHz
omega0 = 2 * np.pi * f0

# 時間範囲(発振の数十サイクル分)
n_cycles = 50
t_end = n_cycles / f0
dt = 1 / (f0 * 100)  # 1サイクルあたり100点
t = np.arange(0, t_end, dt)

# 初期条件(微小な初期擾乱 — 熱雑音に相当)
y0 = [0.001, 0.0]

# 異なるμ(帰還の強さ)でシミュレーション
mu_values = [0.1, 0.5, 2.0]
colors = ['#1f77b4', '#ff7f0e', '#2ca02c']

fig, axes = plt.subplots(3, 2, figsize=(14, 12))

for i, (mu, color) in enumerate(zip(mu_values, colors)):
    # 規格化した方程式を解く
    mu_norm = mu * omega0
    sol = odeint(vanderpol, y0, t, args=(mu_norm, omega0), rtol=1e-10, atol=1e-12)
    v = sol[:, 0]

    # 時間波形
    axes[i, 0].plot(t * 1e6, v, color=color, linewidth=0.5)
    axes[i, 0].set_xlabel('Time [$\\mu$s]', fontsize=11)
    axes[i, 0].set_ylabel('Voltage [V]', fontsize=11)
    axes[i, 0].set_title(f'Time Domain ($\\mu$ = {mu})', fontsize=12)
    axes[i, 0].grid(True, alpha=0.3)

    # 振幅のエンベロープ
    # ヒルベルト変換で包絡線を取得
    from scipy.signal import hilbert
    analytic = hilbert(v)
    envelope = np.abs(analytic)

    axes[i, 1].plot(t * 1e6, envelope, color=color, linewidth=2)
    axes[i, 1].set_xlabel('Time [$\\mu$s]', fontsize=11)
    axes[i, 1].set_ylabel('Amplitude [V]', fontsize=11)
    axes[i, 1].set_title(f'Amplitude Envelope ($\\mu$ = {mu})', fontsize=12)
    axes[i, 1].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('oscillator_transient.png', dpi=150, bbox_inches='tight')
plt.show()

6つのグラフから、発振の起動過程が直感的に理解できます。

$\mu = 0.1$(弱い正帰還、上段)の場合、初期の微小擾乱(0.001 V)が非常にゆっくりと成長しています。包絡線を見ると、指数関数的に振幅が増加し、やがて一定値に収束しています。この「ゆっくりした起動」は、ループ利得が1をわずかに超える程度であることに対応します。定常状態での波形はほぼ理想的な正弦波です。

$\mu = 0.5$(中程度の正帰還、中段)では、起動がかなり速くなっています。数サイクルで定常振幅に達し、包絡線のオーバーシュートもわずかに見えます。波形はまだ正弦波に近いですが、わずかな歪みが観察されます。

$\mu = 2.0$(強い正帰還、下段)では、ほぼ瞬時に大振幅に達しています。しかし、波形を見ると正弦波から大きく逸脱し、緩やかな部分と急峻な部分が交互に現れる「弛張発振」に近い波形になっています。正帰還が強すぎると、非線形効果が顕著になり波形が歪むことがわかります。

これは重要な設計上の教訓です。発振器の起動を速くするためにループ利得を大きくしたい($\mu$ を大きくしたい)のですが、そうすると波形の歪みが増加します。良い正弦波を得るためには、起動後にループ利得が正確に1に近づくようなAGC回路が不可欠であることが、シミュレーションからも確認できました。

水晶振動子のインピーダンス特性

水晶振動子の等価回路から、インピーダンスの周波数特性を計算します。

import numpy as np
import matplotlib.pyplot as plt

# 水晶振動子の等価回路パラメータ(10 MHz水晶の典型値)
L1 = 10e-3       # 運動インダクタンス [H]
C1 = 25.33e-15   # 運動キャパシタンス [fF](f_s=10MHzから逆算)
R1 = 10           # 等価直列抵抗 [Ω]
C0 = 5e-12        # 並列容量 [pF]

# 直列共振周波数と並列共振周波数
fs = 1 / (2 * np.pi * np.sqrt(L1 * C1))
fp = fs * np.sqrt(1 + C1 / C0)

# Q値
Q = 2 * np.pi * fs * L1 / R1

# 周波数範囲(共振付近を高分解能で)
freq = np.linspace(fs * 0.999, fp * 1.001, 10000)
omega = 2 * np.pi * freq

# 直列枝のインピーダンス
Z_series = R1 + 1j * omega * L1 + 1 / (1j * omega * C1)

# 並列容量のインピーダンス
Z_C0 = 1 / (1j * omega * C0)

# 水晶振動子の全インピーダンス(直列枝と並列容量の並列接続)
Z_xtal = Z_series * Z_C0 / (Z_series + Z_C0)

Z_mag = np.abs(Z_xtal)
Z_phase = np.angle(Z_xtal, deg=True)

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 9), sharex=True)

# インピーダンスの大きさ
ax1.semilogy(freq / 1e6, Z_mag, 'b-', linewidth=2)
ax1.axvline(x=fs / 1e6, color='g', linestyle='--', alpha=0.7, label=f'$f_s$ = {fs/1e6:.6f} MHz')
ax1.axvline(x=fp / 1e6, color='r', linestyle='--', alpha=0.7, label=f'$f_p$ = {fp/1e6:.6f} MHz')
ax1.set_ylabel(r'$|Z|$ [$\Omega$]', fontsize=12)
ax1.set_title('Crystal Impedance Characteristics', fontsize=14)
ax1.legend(fontsize=11)
ax1.grid(True, which='both', alpha=0.3)

# インピーダンスの位相
ax2.plot(freq / 1e6, Z_phase, 'b-', linewidth=2)
ax2.axhline(y=0, color='gray', linestyle=':', alpha=0.5)
ax2.axvline(x=fs / 1e6, color='g', linestyle='--', alpha=0.7)
ax2.axvline(x=fp / 1e6, color='r', linestyle='--', alpha=0.7)
ax2.fill_between(freq / 1e6, -90, 90,
                  where=(freq >= fs) & (freq <= fp),
                  alpha=0.1, color='orange', label='Inductive region')
ax2.set_xlabel('Frequency [MHz]', fontsize=12)
ax2.set_ylabel('Phase [deg]', fontsize=12)
ax2.legend(fontsize=11)
ax2.grid(True, alpha=0.3)
ax2.set_ylim([-100, 100])

plt.tight_layout()
plt.savefig('crystal_impedance.png', dpi=150, bbox_inches='tight')
plt.show()

print(f"水晶振動子パラメータ:")
print(f"  L1 = {L1*1e3:.0f} mH, C1 = {C1*1e15:.2f} fF, R1 = {R1} Ω, C0 = {C0*1e12:.0f} pF")
print(f"  直列共振: fs = {fs/1e6:.6f} MHz")
print(f"  並列共振: fp = {fp/1e6:.6f} MHz")
print(f"  Δf = fp - fs = {(fp-fs):.0f} Hz ({(fp-fs)/fs*1e6:.0f} ppm)")
print(f"  Q値 = {Q:.0f}")
print(f"  最小インピーダンス(fs): |Z| ≈ R1 = {R1} Ω")

水晶振動子のインピーダンス特性は、2つの極めて特徴的な点を持っています。

上段のインピーダンスの大きさを見ると、直列共振周波数 $f_s$(緑)でインピーダンスが最小値($\approx R_1$)に達し、並列共振周波数 $f_p$(赤)で最大値に達しています。$f_s$ と $f_p$ の間隔が非常に狭い(わずか数kHz、つまり数十ppm)ことに注目してください。これは $C_1 \ll C_0$ であることの直接的な帰結です。

下段の位相特性がさらに重要です。$f_s$ と $f_p$ の間(橙色の領域)で位相が正、すなわちインピーダンスが誘導性(インダクタのように振る舞う)であることがわかります。この狭い誘導性領域が、水晶をコルピッツ型発振回路の $L$ の代わりに使える理由です。Q値が非常に高いため、発振周波数はこの狭い領域内に高精度で拘束されます。

まとめ

本記事では、発振回路の理論を基礎から体系的に解説しました。

  • バルクハウゼン条件: ループ利得 $|A\beta| = 1$ かつ位相 $\angle A\beta = 0°$ が発振の必要条件。起動時は $|A\beta| > 1$ で振幅が成長し、非線形効果で $|A\beta| = 1$ に安定化する
  • コルピッツ発振器: 2つのコンデンサと1つのインダクタによるLC発振器。発振周波数は $f_0 = 1/(2\pi\sqrt{LC_1C_2/(C_1+C_2)})$、必要利得は $C_1/C_2$
  • ハートレー発振器: コルピッツの双対。2つのインダクタと1つのコンデンサを使用
  • ウィーンブリッジ発振器: RC回路のみで構成される低周波発振器。発振周波数は $f_0 = 1/(2\pi RC)$、必要利得は $A = 3$
  • 水晶発振器: 圧電効果とQ値10万以上の超高Q共振を利用。$f_s$ と $f_p$ の間の誘導性領域でコルピッツ型回路を構成
  • VCO: バリキャップやリングオシレータにより発振周波数を電圧で制御。PLLの中核部品

発振回路は「信号を自発的に生み出す」という能動的な機能を持ち、あらゆる電子システムの時間基準を提供しています。VCOを帰還ループに組み込んで周波数を精密に制御する仕組みがPLL(位相同期ループ)であり、現代の通信・クロック生成技術の基盤です。

次のステップとして、以下の記事も参考にしてください。