AD9833 + STM32でファンクションジェネレータを作ってみる

こんにちは PIC MANです。

ファンクションジェネレータ、皆さんはお持ちですか?我が家にはありません。。いつかほしいな~と思いつつ、ちゃんとした機器を買うとなるとそれなりにお値段もするので買わずじまいでした。そんな折、AD9833というプログラマブル波形発生器を見かけました。

このAD9833は、正弦波や三角波、矩形波をデジタル制御で出力することができるものです。単品で買おうとすると秋月では約1,500円Digikeyでも約2,400円とそこそこのお値段します。しかし、Amazonやアリエクではクロックの水晶やコンデンサが乗ったモジュール基板が数百円で売られています。Amazonだと約1,000円アリエクではなんと500円ほどです。面白そうなので買って試してみることにしました。

AD9833概要

おおまかな仕様は下記のとおりです。

  • 周波数範囲:0~12.5[MHz]
  • 分解能:28[bit](25[MHz]のクロックで0.1[Hz])
  • 出力波形:正弦波、三角波、矩形波
  • 出力振幅:
    • 正弦波、三角波:0.038~0.65[V]固定
    • 矩形波:電源電圧
  • IF:3線SPI

ホビーユースのファンクションジェネレータとして使うと考えると、0.1[Hz]単位で制御できるのは十分すぎるくらいですが、出力振幅が固定であったり、波形によって異なるという部分はちょっと困りますね。この部分は自分でアナログ回路を組む必要がありそうです。また、IFがSPI通信となっている部分はマイコンから制御がしやすくていいですね。

設計

ここから、AD9833を使ったファンクションジェネレータを作っていきます。まずは設計です。

概要

今回は、AD9833とそれを制御するマイコンを中心に1枚のプリント基板で操作・出力が完結することを念頭に開発することにしました。具体的な要件としては下記を挙げました。

  • スタンドアローン(制御用のPCなど不要)で動作し、基板上で出力波形の操作ができる
    • 周波数を操作できる
      • 少なくとも~1[MHz]までは出力できる
    • 振幅を操作できる
      • R2R(電源電圧フルスイング)で動作させることができる
    • 波形を選択(正弦波、三角波、矩形波)できる
    • 現在のパラメタを出力できる(e.g., キャラクタ液晶に周波数を表示)
  • USB Type-C接続で手軽に動作させることができる
    • USBにつないで電源をとることができる
    • FWのアップデートができる
  • 信号生成用の電源は外部からとることができる
    • 両電源で少なくとも±5[v]くらい

回路設計

上記で挙げた要件をベースに必要なものをまとめました。前提として、JLCPCBのPCBA(プリント基板製造+アセンブリ実装)を試してみたく、そちらで調達可能な部品(特に面実装系)で検討しています。

波形出力部

波形出力のベースにはもちろんAD9833のモジュール基板を使います。この出力をオペアンプを使って振幅/オフセットを操作できる回路を考えます。理想としては、2つのボリュームがあり、振幅とオフセットをそれぞれ操作できるような形をイメージしています。

シミュレーション段階の回路は(とても見づらいですが)下記のような構想でした。

非常に分かりにくいので、まずは簡単な説明を。

オペアンプはR2Rオペアンプで、なるべく動作範囲が広いものを探したところ、(お値段を除いて)AD823Aがよさそうだということになりました。AD823Aは単電源だと3~36[V]で動作し、AC特性も17MHzで-3[dB]と今回の要件に適しています。

先ほどの図ではこのAD823Aをふんだんに利用しています。初めに、肝となるのが3段目、4段目のオペアンプU3, U4です。両方とも反転増幅回路の構成となっています。オペアンプU3はR7,R8をボリュームに見た立てており、この割合を操作することで増幅率が変わります。これにより出力の振幅を操作します。オペアンプU4も同様にR9,R10をボリュームに見立てており、この割合を操作することで正入力端子にかかる電圧を変えてオフセット電圧が変化するようになっています。

1段目のオペアンプU1は単純なボルテージフォロワです。これは、AD9833は出力抵抗が200[Ω]と高いため、出力をそのまま使いたい場合はバッファをかましたほうがいいだろうと考え挟みました。2段目のオペアンプU2はサレンキー型のアクティブLPFになっています。例えば、クロック25[MHz]で1[MHz]の出力をした場合は1周期25ステップでの出力になるため、波形がガタガタすることが予想できるため、滑らかな波形を出力するためにはLPFが必要です。サレンキー型LPFは「AD9833」でググるとよく出てくるので取り入れてみました。たしかに、RやCを使ったパッシブフィルタよりも定数の自由度が大きく設計しやすいです。図中ではカットオフ周波数は約10[MHz]としています。

LPFカットオフのシミュレーション

このフィルタからの出力を、DCカット用のコンデンサC1を通してオペアンプU3につないでいます。

制御マイコン

マイコンはSTM32L432KCU6を使うことにしました。選定理由はNUCLEO32の開発ボードがあり情報が手に入りやすいこと、今回の用途ではこれくらいの規模でいいかなと思った、との2点になります。STM32として小規模なマイコンながらFlash256[KB]、SRAM64[KB]もあるのでいろいろ遊べそうです。

外部クロックは乗せようか迷ったのですが、内蔵発振器で動かす程度の精度で十分なことと、万が一マッチングがとれてなかったりしたらデバッグで永遠に悩みそうなので止めました。

そのほか、デバッグ端子およびBOOTピンをピンヘッダに出しておくことにしました。具体的には、SWCLK,SWOのピンです。これらのピンをST-Linkやお手持ちのNUCLEOボードの頭の部分(コレも結局はST-Linkですが)に繋ぐことで容易にデバッグすることができるようになります。またBOOTピンは論理をVcc/GNDに切り替えることで、DFUブートローダの起動/ユーザープログラムの起動かを選択することができます。先述のデバッガ接続でも内蔵フラッシュへプログラムの書き込みができますが、万が一の回路のミスに備えて複数の書き込み手段を用意しておくと安心です。

さて、DFUで起動した後どうやってプログラムを書き込むのかという話になりますが、今回はUSB – UART変換チップを経由してシリアル通信で書き込めるようにしました。電源取得にも使っていたUSBのデータ線を変換チップに接続し、さらにPA9,10のUSART1に接続することでDFUが使えるようになります。ここら辺の話はAN2606に詳しく記載されています。

UI

スタンドアローンで動作させたいことから、単体でも操作しやすいようにボタンやらLCDやらいろいろ乗せる必要があります。

初めに入力部分です。今回は汎用的に使えるように、タクトスイッチ×5(十字型+センター)、ロータリーエンコーダを乗せることにしました。つまみをぐりぐり回して周波数を設定できたら便利そうです。

次に出力部分については、キャラクタ液晶と有機ELディスプレイのどちらかを乗せられるようにしました。キャラクタ液晶前々からよく使っていてすぐ実装できるのですが、あまり面白味がないので電子工作でよく見かける0.96インチの有機ELディスプレイも使えればという思いがあります。

どちらもI2C接続ですが、微妙に配線が異なるのでそれぞれに合った配列でつなげるようにしました。I2Cなのでパラにぶら下げることもできますが、面積を食うので配置的には排他になりました。今回は、まずはキャラクタ液晶で画面を作ることにしました。画面と遷移イメージは下記を想定していました。

製造(できたもの)

上記の設計を踏まえて作ったものが下記になります。

回路

デジタル部・全体

初めに全体の回路図です。

左上はUSB Type-Cコネクタです。CCピンを5.1[KΩ]でプルダウンすることで5[V]の電源をとることができます。USBからの電源ノイズを通さないように、フェライトビーズを通して後段のレギュレーターに電源を供給しています。また保護ダイオードを電源ライン、D+, D-に入れています。左下はUSB-UART変換チップのCP2102Nです。FTDIのチップを使うか迷ったのですが、こちらの方が安かったのでCP2102Nにしました。

右側は制御マイコンのSTM32L432とAD9833モジュールです。ここにつながるボタン類やアナログ回路類は別シートとしていますので後ほど。そのほかはほとんどピンヘッダ・ピンソケット類になります。

  • デバッグ用端子
  • ブートセレクトピン
  • 液晶モジュールのソケット(×2種)
  • 拡張用のIOピン出力

アナログ部

アナログ部はAD9833の出力をフィルタかけたり振幅を変えたりオフセットを変えたりする部分になります。

左上はアナログ部用のレギュレーターです。一応デジタル部と分けておきました。また、右上は電源選択回路です。レギュレーターからの電源だけではなく、外部から電源を入力できるようにしています。

下部はアナログ部のメインとなる波形調整回路です。設計時の回路構成とほぼ同じですが、下記の変更点があります。

  • 2段目のオペアンプのフィルタをON/OFFできるようにした
  • DCカット用のキャパシタをショートできるようにした
  • 3段目のオペアンプの増幅率を変更できるようにした

UI部

UI部はあんまりおもしろくないですがタクトスイッチとロータリーエンコーダです。ロータリーエンコーダの出力を反転させるために74HC14のNOT ICを入れています。贅沢にも6ゲート中2個しか使っていません。できればタクトスイッチの方もこれを利用したかったのですが、ゲートが1つ足りないのでこのような形になりました。

基板

上記回路をレイアウトし、JLCPCBに発注した結果、基板はこんな感じになりました。

基板は4層で作りました。配線がしやすくていいですね。PCBAで実装してもらった部品がほとんどで、自分ではんだ付けしたのはピンヘッダとソケット、ボリューム、ロータリーエンコーダ、スイッチ程度です。右側にフラックス?のような汚れが残っている基板もありましたがここら辺は中華クオリティといったところでしょうか。

お値段は最小発注枚数の5枚で$121程度でした。おかしいな、格安DDSモジュールを使って遊ぶはずだったのですがこんな値段になってしまうとは。。。金額の内訳としては、下記のとおりです。

  • 総計:$121.88
    • PCB:$30.80
    • PCBA:$79.16
    • 送料:$11.92

敗因としては、思ったより部品代が高かっとこと、基板サイズが大きくなってしまったことでしょうか。もう少し頭をひねって基板サイズを小さくしようかとも思ったのですが、使い勝手的にこの配置からよりよくできなさそうだったのでこのまま発注しました。

発注時の注意点として、最終的な部品配置の確認画面でいくつか向きが間違っているものがありました。間違っていてもその場で修正することができ事なきを得ました。今回は下記の部品の向きが間違っていたので、同じ部品を利用する際は要注意です。なお、自分の開発環境はKiCad8.0を利用しています。

  • タンタルコンデンサ(C7182, C7171)
  • STM32L432KCU6(C1337280)
  • ダイオード(C3040626)
基板上のシルクの1ピンマーク(▼)と、部品の1ピンマーク(ピンクの●)が90度ずれている(心臓に悪い)

ソフトウェア

下記リポジトリで作っています。

https://github.com/pic-man749/DDS_dev_kit

ソフトの方はあまり書くことがないのですが、おおむね設計時の画面イメージに沿って作っています。基本的にはC++言語を利用し、画面(スクリーン)をステートにしたようなステートパターンもどきがベースになっています。また各ペリフェラルの初期化はCubeMXの自動生成コードを利用しています。さらに、AD9833やキャラクタ液晶のドライバはHALライブラリを利用しています。

補足ですがコントラストを調節する設定画面はサボっていてまだ作っていません。また、波形選択画面での波形の変更は、当初ロータリーエンコーダでする設計でしたが、使ってみて左右ボタンでの操作のほうがよかったので変更しています。

動作確認

実際に動かしてみるとこんな感じです。

周波数設定画面では、左右キーで桁を選択し、ロータリーエンコーダで数字を上げ下げできます。また、左のボリュームが振幅、右のボリュームがオフセットを操作できます。

出力波形の評価はこれからじっくり行いたいと思いますが、おおむね1MHzまでの波形であれば歪まず出力できていました。

課題

作って動作確認した段階での課題点です。

波形出力のオフができない

これは完全に見逃していたのですが、この回路は出力を完全にオフにすることができません。一応センターのボタンでAD9833からの出力をオンオフできるようにしていたのですが、アナログ回路部でオフセットを触っている関係で、オフにしても中心電圧で出力が出っぱなしになっています。電圧源として使えなくもない。ちゃんと最終出力部をリレーか何かでオフにできるようにすればよかったなと思った次第です。

そこそこノイズが乗る

USBから電源を引っ張っている、というのもありますが、出力OFF時でもそこそこノイズが乗ります。下記に、電源別の測定波形を載せます。モニタのUSBハブから取得した場合ではかなりヒゲが目立ちました。これはUSBでデータ通信が行われている際に発生するのではないかと予想しています。また、最後に0-3.3[V]で正弦波を出力した際のFFT波形も載せておきます。まあまあピークがきれいに見えました。SN比は60[dB]くらいでしょうか。

今後の展望と所感

ノイズ回りをもう少し気にして設計できるようになりたいなと思いました。特に電源からのノイズを除去する部分と、オペアンプ周りのアナログ回路です。詳細な評価をしてどう改善すればノイズを低減できるか調査していきたいです。

ボリュームやロータリーエンコーダを3つも載せてしまうとそこそこ面積を食うので、ロータリーエンコーダ1つ+デジタルポテンショメーターで増幅率やオフセットを操作できるようにしてもいいなと思いました。次回作を作る機会があればそうしたいですね。

UI的な意味での入力と出力部をリッチ(?)にしていたので、プログラムでの遊び甲斐がありました。この点に関してはよかったなと思います。

PIC MAN

ソフトとハードの両方の目線を持てるようになりたいです.

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です