ELM Home Page

初出: 絶縁破壊技報 No.1(C70)
Web Version: 2007. 3. 14

DDSファンクション・ジェネレータ


Front Panel

自作測定器の定番、ファンクション・ジェネレータの製作です。ファンクション・ジェネレータとは、テスト信号を生成する汎用発振器の一種で、正弦波や矩形波を始め任意の波形を出力できるものもあります。単純なものなら簡単に製作できるため、古くから自作測定器の定番となっていました。ファンクション・ジェネレータの信号生成方式には大きく分けて、アナログ式とデジタル式があります。

アナログ式としては、ウィーンブリッジ発振回路を使用したものや、古のファンクション・ジェネレータIC ICL8038 を使用した製作例が古くから見られました。これらのアナログ方式は製作が手軽な反面、調整が面倒で設定精度や安定性に欠ける欠点があります。

最近増えてきたデジタル式は、デジタル回路を使用した演算により波形を合成して、その波形データをD-Aコンバータでアナログ信号に変換・出力するものです。これはいわゆるDDSと呼ばれている方式です。デジタル回路で波形を生成するため、アナログ式に比べて安定性・再現性が極めて高く、周波数等の設定も瞬時に行えるのが特徴です。今回は、このDDS方式でファンクション・ジェネレータを製作してみます。

DDSの原理

連続信号と離散信号

連続信号と離散信号

時間軸で連続している信号(連続信号)をデジタル回路で処理する場合、まず一定時間毎の瞬時値をサンプリング(標本化)してそれをデジタル・データに変換(量子化)していくことになります(図1)。サンプリングされた信号の値はサンプリング・ポイントだけに存在し、その間には有効な値が存在しません。このような信号を離散信号といいます。デジタル信号処理では基本的に離散信号を扱うことになります。

離散信号は連続信号と等価に扱うこともできますが、特有の性質もあるので注意が必要です。たとえば、離散信号ではサンプリング・ポイントの間の波形情報が無いため、サンプリング・レートよりも速く変化する信号は正しく表現できません。サンプリング周波数 fs [Hz] の場合、正確に表現可能な信号周波数は fs / 2 [Hz] 以下となります。これをナイキスト周波数といいます。サンプリング・レートを上げるほど広い帯域の信号を扱えることになりますが、システムの資源は有限なので、サンプリング・レートはそれぞれの処理対象において必要最小限な値が選ばれます。

離散信号について、「繰り返し周波数 fs のインパルス信号を元の信号でAM変調したもの」と考えると、その性質を理解しやすくなります。離散信号を周波数領域で見たとき、 fs * N 毎に元の信号のスペクトラムが無限に投影される理由もよく分かると思います。

波形のデジタル合成

波形をデジタル合成する場合は、デジタイズとは逆のプロセスを辿ります。つまり、サンプリング・ポイント毎の瞬時値を算出することによりデジタル信号(波形データ)を作って、それをアナログ変換して出力していくことになります。例として正弦波を合成する場合を考えてみます。正弦波の瞬時値eは、 e = Ep・sin(θ) = Ep・sin(ωt) = Ep・sin(2πft) …(1) により算出できます。ここで、Epはピーク値、ωは角速度[rad/sec]、fは周波数[Hz]、tは経過時間[sec]を意味します。これに従ってサンプリング・ポイント毎の t からその瞬時値 e を求めていけば正弦波のデジタル信号が合成できます。これは正弦波に限らずどのような信号 f(t) でも t の関数であるかぎり全く同様です。

DDSのハードウェア

波形テーブル

DDSを実現するとき、その都度sin関数を計算していたのでは回路規模や速度の点で不利です。そこで、sinが周期関数であることに着目し、1周期分の値をテーブルに保持して、角度 θに対応する値をテーブル変換すれば図2に示すような単純な回路で実現でき、劇的に高速化できます。もちろん、正弦波以外のどのような信号でもテーブルにフィットする周期信号なら同様に合成できるので、電子楽器(WaveTable方式)など測定器以外にも広く応用されています。これにより合成される信号の周波数fは、 f = fs・(1 / Ns) …(2) となります。fsはサンプリング周波数、Nsはテーブル長です。ここで、f を変化させようとした場合は fs を変えるのが自然ですが、アナログ系との兼ね合いもあり fs を可変にするのは好ましくありません。でも、f の変更はポインタのサンプリング毎の増加量(Δs)を変えることでも可能です。 f = fs・(Δs / Ns) …(3)

DDS

この処理を図3に示します。ブロック図から分かるように、θレジスタにはサンプリング毎にωレジスタの値が加算されるので、これを書き換えるだけで周波数を設定できます。しかも1/N分周器とは違い、設定値と周波数は正比例関係になるので、とても扱いやすいといえます。この図に示す構成がDDSの基本型となっていますが、実際のDDSシステムではωレジスタとθレジスタに小数部が設けられ、非常に高分解能な周波数設定が可能になっています。しかし、テーブル参照時の小数部切り捨てにより位相エラーが生じ、出力信号の位相ノイズが悪化するDDS特有の欠点にもなっていて、用途によっては何らかの対策が必要になります。位相ノイズを減らすにはθレジスタの小数部でデータを補間したり、テーブル長を大きく取るなどします。

仕様の検討

まず、ファンクション・ジェネレータの仕様を次のように設定しました。

  1. DDS方式で実現する。
  2. 主にオーディオ・システム向けに使用する。
  3. 振幅も含めて全てデジタル設定とし、アナログ設定器は排除する。
  4. 正弦波のほか、さまざまな任意波形を発生する。

これらの基本仕様は、1.はこのプロジェクトの目的なので当然として、2.は最も汎用性が高いと考えられるため、3.はアナログ設定器は不正確だから、4.は正弦波だけではつまらない、という理由から設定してみました。

DDSの実現方法

DDSの実現方法にはハードウェアだけで構成する方法と、DSP等によるソフトウェア演算を併用する方法があります。ハードウェア式としては、ワンチップDDS ICを使う方法やPLD等で演算回路を組む方法があります。

DDS ICはデジタル通信システム向けに設計されているため、DAC分解能が10ビット程度と低く、正弦波出力しかできない、レベルが固定である、など考えている仕様には合いません。PLDでDDS回路を組めばこの辺は自由に設計できます。でも、いずれにしろシステム制御にマイコンを使うことになるので、ついでにマイコンでDDSを実現できないか考えてみます。

オーディオ帯域をカバーするには少なくとも100kspsは欲しいところなので、16bit, 100kspsのDDS処理がマイコンで可能か検討してみます。その結果、計算上はいつものAVRマイコンで何とか実現できる目処が立ちました。バックグランドのDDS処理の負荷率は80%以上が見込まれ、ほとんど余裕がありませんが、実現は可能と判断しました。このような処理は本来DSPの領分ですが、8bitマイコンで可能なことをわざわざDSPを持ち出してまでやる必要はないでしょう。

出力

手持ちのオーディオ用ステレオDACを使用することにしたので、出力を2チャネル確保できます。これによりアンプのIMD特性の実験や、任意の位相差、複素信号の生成など面白い実験ができそうです。

ユーザI/F

ディスプレイには20桁×4行のキャラクタLCDモジュールを使用します。2チャネルあるため表示すべき情報が多く、2行では足りません。入力は4方向ボタンとロータリ・エンコーダだけとシンプルにしました。ボタンで変更したい項目にカーソルを合わせて、ロータリ・エンコーダで設定するので、1軸で足ります。波形データは、メモリ・カードに格納して設定します。

ハードウェア

Fig.4

図4にファンクション・ジェネレータの機能ブロック図を示します。次に各ブロックについて説明します。
回路図(制御部) | 回路図(アナログ部)

コントローラ

アトメルのATmega64を使用します。これは外部メモリI/Fを持っているので、今回のようにある程度の容量のRAMが必要なときは重宝します。波形データはMMCから外部RAM(256Kビット)に読み込まれ、それを波形テーブルとします。波形テーブルは 16ビット×8192サンプル×2チャネル でちょうどRAMのサイズにフィットします。システム・クロックは、DACのオシレータ出力から19.6608MHzを調達しています。このマイコンの動作クロックは最大 16MHz@5Vですが、この程度のオーバーなら問題なく動作します。

PLD

Fig.5

図5にPLDの機能ブロック図を示します。PLDの主な目的は波形データをパラレル-シリアル変換してDACに送ることですが、容量が余っているのでAVRの外付け回路として必要なメモリI/Fも一緒に入れています。DACへのLRCKは同時にマイコンへの割り込み信号として、データ出力のタイミングを取るようにしています。PLDには手持ちのLattice ispLSI1016Eを使用しました。これは64マクロセル以上のCPLDならどれでも置き換えが可能です。

DAC

DACにはNECのステレオ・オーディオDAC μPD63210を使用します(若松にて購入)。これは抵抗ストリング型16bit DACに、8倍オーバー・サンプリング・デジタル・フィルタを内蔵したものです。デジタル・フィルタによりDA変換前に入力帯域付近のエイリアスをほぼ完全に除去してくれるので、簡単なポスト・フィルタでも入力ナイキスト周波数付近まで歪み無く波形を再生することができます。このDACは、96kHz入力が可能なので、一般的なオーディオ帯域の倍の40kHz以上の信号も再生できます。もちろん、これ以外の多くの96kHz対応のオーディオDACでもそのまま使用可能です。今回は、基本周波数が12.5Hz(@8192pts)とキリのいい値になるようにマスタ・クロックを少し変更して102.4kHzのタイミングで使用しています。DACの電源が汚いとスプリアスの原因になるので、+12Vからシリーズ・レギュレータで落として、AVDDとDVDDへそれぞれLCフィルタを通して供給します。

アナログ部

DACは単電源で出力にDCオフセットがあるため、それをキャンセルしたあと、減衰率(1/1と1/16)をタップ切り替え、バッファして出力します。アナログ・アッテネータを併用する理由は、出力レベルの可変範囲がとても広く、デジタル・アッテネータだけでは電圧レベルを下げたとき有効ビット数が著しく減少してしまうからです。

ソフトウェア

DDS処理

Fig.6

図6にDDS処理のブロック図を示します。プログラムの処理としては、サンプリング割り込み毎に V1 = WaveTable1 [(θ1 += ω1) % 8192] * Gain1;
V2 = WaveTable2 [(θ2 += ω2) % 8192] * Gain2;
の演算を実行・出力しているだけです。ωとθはそれぞれ固定小数点レジスタ(整数部13bit、小数部17bit)となっています。しかし、これらの演算は102.4kHzのレートで処理しなければなりません。サンプル間に与えられるCPUクロック数は、わずか192クロックとなり、アセンブラで記述して何とか間に合うかどうかといった感じです。

Fig.7

いろいろ試行錯誤した結果、ロード・ストアのタイム・ロスを減らすため、レジスタ変数を静的に割り当てるという荒技を使い、割り込み応答から終了までを157クロックに削減できました。負荷率は82%程度になり、DDS動作中も3MHz程度のCPUパワーが残る計算になります。このタイミング・チャートを図7に示します。割り込み応答の遅延は致命的なので、他の割り込み処理中には多重割り込みを許可して、DDS処理が最優先で実行されるようにします。なお、ファイル・アクセス(波形テーブルの更新)をするときはDDSは停止されるので、ファイル制御モジュール内では静的レジスタ割り当てを宣言していません。

波形データ管理

波形データは普通のcsvファイルでメモリ・カードに記録しておきます。フォーマットは、1行に2列(ch1,ch2)で8192行、値の範囲は-32767~32767の整数、ピーク値が32767または-32767になるようにノーマライズとします。また、波形リストを管理するため、インデックス・ファイル(index.txt)を設けて、これに表示名とファイル名の対応を記述し、リスト上の順番を決めるようにしました。

波形データはcsvファイルを基本としますが、テキスト処理のオーバーヘッドが大きく、波形の切り替えに2秒ほどかかります。そこで、csvファイルを読み込んだとき、波形テーブルと波形特性(クレスト・ファクタやP-P値)をバイナリ・ファイル(.bin)にキャッシュしておきます。これにより、次からそれらの情報を直接バイナリ・ロードできるので、劇的に高速(50ms程度)に切り替えできるようになります。キャッシュの有効判定はタイムスタンプの一致比較(キャッシュ・ファイルはcsvファイルと同じタイムスタンプで作成するためRTCは不要)で行います。メディア交換を検出したら、DDSを停止してインデックス・ファイルを再読込します。

ユーザI/F

トップの写真にフロント・パネルを示します。LCDには、上から順に、波形、出力電圧、Ch1周波数、Ch2周波数、Ch2位相が表示されています。操作は、↑↓←→ボタンで変更したい数字や項目にカーソルを移動してダイアルで変更するだけです。波形を切り替えるときは、ダイアルで波形を選んだ後、→ボタンで決定します。

写真は位相固定モードの状態で、Ch1の周波数を変更するとそれに追従してCh2周波数が変化します。Ch2のCh1に対する位相は任意に設定できます。Ch2の周波数を変更すると2トーン・モードになり、位相表示が***に変わって、Ch1とCh2で別々に周波数を変えられます。位相を動かすと再び位相固定モードに設定されCh2周波数はCh1に固定されます。

オーディオ・システムではHi-Z受けで使うことが多いので、電圧は全てEMF表示としました。電圧の単位を変更するときは、そこにカーソルを合わせてスクロールです。dBm表示は、600Ω基準なので、0dBmは775mVRMSとなります。実際に600Ω負荷をつなぐと、Zo=50Ωとの分圧となり、表示より0.7dBm低下します。正弦波では5VRMS程度の出力が可能ですが、選択した波形のクレスト・ファクタによっては設定可能な電圧は低下します。

組み立て

デジタル・アナログ混載のシステムなので、基板の組み立てには相応の配慮が必要です。といっても、セオリー通りやれば特に難しい点はありません。基板が出来たら、ほかの部品といっしょにケースに詰め込んで終わりです。

調整

マイコンとPLDに書き込んだら、一通りの機能が正常に動作して波形が出力されることを確認します。そして、標準器とするAC電圧計を用意しておきます。

まず、波形出力が停止している状態でアッテネータ抵抗への入力電圧が0VになるようにVR1とVR2を調整します。次に、5VRMSの正弦波を出力して両チャネルとも5VになるようにVR3とVR5を調整します。そして、電圧を下げてアッテネータが切り替わる前後(0.34V近辺でU5-10がLからHに変化)の出力電圧がスムースに切り替わるようにVR4とVR6を調整します。最後にMCLKの周波数を周波数カウンタで測って、19.6608MHzになるようにVC1を調整します。無調整でもファンクション・ジェネレータとしては十分な周波数確度なので、この調整は省略してしまっても特に問題はありません。

結果と考察

各部の波形

位相固定モード2トーン・モードの例です。それぞれのチャネルには異なる波形をロードできるので、複素信号を発生することもできます。周波数切り替えはDDSなので瞬時に連続位相で、波形切り替えは、バイナリ・キャッシュの効果により瞬時(約55ms)での切り替えを実現しています。矩形波を出力してみたところ、波形のエッジにデジタル・フィルタ特有のリンギングが現れています。それから、ナイキスト周波数に近い40kHzの正弦波出力。LRCKの立ち上がりがDAC入力のサンプリング・ポイントです(フィルタでの遅延により出力波形との位相関係は正しくはない)。入力データは非常にまばらですが、オーバーサンプリング(約820kHz)とデジタル・フィルタによる補間で正弦波として正確に再現されています。

性能の確認

出力信号の特性を測ってみたところ、THD+Nは出力レベルを変化させていくと 0.01%~0.03% の間を上下します。これは、デジタル・アッテネータの演算誤差によるものと思われます。10mV以下の微少電圧ではノイズの影響も出て数値はさらに悪化します。SN比は85dB (1kHz, 1VRMS)となりました。なお、これらの値は全てJIS-Aフィルタ適用時の値です。DACの生の性能から考えると、まぁ妥当なところといえるでしょう。このように、オーディオ信号発生器としてはとりあえず悪くはない結果となりました。欲を言えば100kHzまで欲しかったところですが、使用したDACとマイコンの性能の限界ということで仕方ありません。

使い勝手を大きく左右するユーザI/FではLCDディスプレイ、カーソル・ボタン、ロータリ・エンコーダをうまく連携したことにより、煩雑な設定がスムースに行えました。

資料

ファンクション・ジェネレータの仕様
主要ICMCU: ATmega64 (ATMEL)
PLD: ispLSI1016E (Lattice)
DAC: UPD63210 (NEC)
DDS機能 チャネル数: 2
サンプリング・レート: 102.4ksps
量子化ビット数: 16bit
波形テーブル長: 8192pts/ch
アナログ出力Zo=50Ω, 2ch
設定周波数
(Ch1/Ch2個別)
0.01Hz~45,000.00Hz (0.01Hz step)
設定電圧
(Ch1/Ch2共通)
0.001~20.000VRMS (0.001VRMS step)
0.001~20.000VP-P (0.001VP-P step)
-60.00~+20.00dBV (0.01dBV step)
-60.00~+20.00dBm (0.01dBm step)
(全てEMF表記、ピーク電圧±7.5V以下)
Ch2位相表示-180°~+179°
(Ch1基準, 1° step, wrap-around)
ユーザI/FキャラクタLCDモジュール(20桁×4行)
ボタン×4、ロータリ・エンコーダ×1軸
ボタン・ダイアル操作のクリック音
波形記録メディアMMCまたはSDC
電源AC100V

図と写真

参考文献

Sign