部品屋根性(113) AD9837、プログラマブル波形生成器、M5Stackで生成テスト

Joseph Halfmoon

今回試用してみるデバイスはDDS(ダイレクト・デジタル・シンセサイザ)です。正弦波、三角波、矩形波などの波形をお好みでシンセサイズしたのち、DAコンバータを介してアナログ出力できるもの。ディープな用途には必携?らしいデバイスであります。動作させるためにはホストのマイコン必要。今回はM5Stackを使ってテスト。

※「部品屋根性」投稿順Indexはこちら

ダイレクトデジタルシンセサイザ(DDS)

以下のアナデバ様の製品ページ(日本語)では素直に「プログラマブル波形生成器」とタイトルされております。

AD9837 プログラマブル波形生成器、2.3V~5.5V、低消費電力8.5mW

カッコいいデバイスらしくパッケージはLFCSPのみ。私ははんだ付けすることができませぬ。しかし、いつものように秋月電子通商殿からDIP化モジュール(米国式に言うとブレークアウト・ボード)がでてます。ピンヘッダをはんだ付けすればOKっと。

AD9837_ON_BB

ホストにはMicroPython搭載のM5Stack

「シンセサイザ」であるだけに、波形や周波数、位相といった項目をデジタルな数値で指定しないとなりませぬ。そのインタフェースはSPIです。よってSPIマスタになれるデバイスが必要です。そこで今回は別シリーズでMicroPython (UIFlow2版)を書き込んで使っているM5Stack Gray をホストにして動作確認してみることにいたしました。回路はこんな感じ。AD9837_DUT_Schematic

 

ESP32マイコンを搭載するM5StackはハードウエアのSPIも搭載しているのですが、内部で他の用途に「いろいろ」使っているのでハードウエアSPIのチャネルには接続せず、GPIO端子をソフトウエアSPIで使用することにいたします。

なお、AD9837はデジタルにシンセサイズする回路であるだけにクロックが必要です。今回は、後に述べるアプリケーションノートの関係で25MHzのクロックが欲しかったです。M5Stack(ESP32)上のMicroPythonで25MHzクロックを生成させる方法については別シリーズの以下記事でやってます。

MicroPython的午睡(134)M5Stack UIFlow2、CLOCK出力

テストに使用したMicroPythonスクリプト

今回は 400Hzの正弦波を生成してみています。これはアナデバ様の以下のアプリケーション・ノートで設定値などが書かれていたので、その値をそのままコピペして設定したものです(あざ~す。)

AN-1070 AD9833/AD9834 の設定方法

なお、上記のAD9833/AD9834と今回のAD9837の設定方法は同じということみたいです。知らんけど。

上記アプリケーション・ノートの設定値を流し込むスクリプトをMicroPythonで書いたものが以下に。

# AD9837sinwave400Hz.py

import machine
import M5
import time

mclkOutPin = 5
PWMfreq = 25000000
PWMduty = 512 #50%
CSpin= 2
SCK=machine.Pin(16)
MO=machine.Pin(17)

def main():
    M5.begin()
    print("M5STACK, testAD9837.") 
    cs = machine.Pin(CSpin, mode=machine.Pin.OUT, value=1) 
    mclkOut = machine.PWM(machine.Pin(mclkOutPin), freq=PWMfreq, duty=PWMduty)
    ad9837 = machine.SoftSPI(baudrate=100000, polarity=1, phase=0, bits=8, firstbit=machine.SPI.MSB, sck=SCK, mosi=MO, miso=machine.Pin(25))
    cs(0)
    ad9837.write((0x2100).to_bytes(2, 'big')) # RESET(Disable OUTPUT)
    ad9837.write((0x50C7).to_bytes(2, 'big')) # Set Freq Low
    ad9837.write((0x4000).to_bytes(2, 'big')) # Set Freq High
    ad9837.write((0xC000).to_bytes(2, 'big')) # Set Phase
    ad9837.write((0x2000).to_bytes(2, 'big')) # Enable OUTPUT
    cs(1)

    loopCounter = 0
    while True:
        loopCounter += 1
        print("LOOPCOUNTER: ", loopCounter)
        time.sleep(10)
            
if __name__ == "__main__":
    main()

なお、AD9837のレジスタ幅は16ビットなのですが、ESP32版のSoftSPIの場合、ビット幅は8ビットのみ許されるようです。そこで8ビット設定で、必ず2バイト連続で送信してます。MSBファーストなのでバイト順はbig endianね。

また、AD9837の制御はライトオンリなのでMOSIだけあれば良いのです。しかし、miso=Noneと設定したらエラーになったので、急遽、ここでは使っていないPin(25)にmisoを押し付けてます。

実機動作確認

実機上で上記のスクリプトを動かした結果の波形が以下に。ResultSineWave

周波数約400Hz、ピークツーピークの振幅約610mV、ほぼほぼ予定通りでないかい。

部品屋根性(112) AD8656でトランスインピーダンスアンプ、赤外線リモコン生波形 へ戻る

部品屋根性(114) USB On-The-Go ケーブルでラズパイPicoをスマホ接続 へ進む