ja1yaz’s diary

感動したいおやじの備忘録的ブログ 

AD9833モジュールを使いこなしたい(1)

Si5351Aは、大分わかってきたので、次に進むことにした。

以前購入していた、DDSモジュール、AD9833モジュールだ。

AD9833モジュール+Raspberrypi Pico

実は、数日かかりきりでやっていたのでした。

まずRaspberrypi picoでSPIをまともに動かしたことがないので、とても基本的なことからわかっていなかった。

Raspberrypi Picoには、SPI0とSPI1がある。

ピンが近いので、SPI1の方を接続していたら、どうしてもSPIの設定ができなくていい加減悩んでいた。

 

spi = SPI(0, baudrate=8000000, polarity=0, phase=0, bits=16, firstbit=SPI.MSB,sck=Pin(14),mosi=Pin(15))

 

するとどうしてもSCLKの設定がおかしいというワーニングが消えないのです。

いまだにGP10-13のグループとGP14,15の関係がよくわかっていなんですけど・・・

 

これは、SPI0に接続することで解決したのだった。

また、SPIのピンには、SCLK、SPI TX  SPI Rx  SPICSnが存在する。

CLK、MOSI,MISO,SSに相当するものだ。

私は、勝手にSPI CSnは自動的に動作してくれるものだとばかり思っていた。

それにしては、SPIの宣言文にSS(CSn)の設定がないのはおかしいなと思っていたら、オシロで見てみると、なんと何も動いていないではないですか。

これでは動くはずがありません。Pin設定してSPI CSnのピンにアサインして、プログラムで動かすところまで行った。しかしこれでもどうしても動かない。

 

spi = SPI(0, baudrate=8000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB,sck=Pin(18),mosi=Pin(19))
cs=Pin(17,Pin.OUT)

 

と設定していた。この見方自体がよくわかっていなかったのだ。

AD9833のデータシートを見るとクロックの立下りエッジでデータを読み込むようになっているのが分かった。オシロで見てみると、どう見てもクロックの立ち上がりエッジでデータを読み込む感じになっているではないか。

もしかして、この polarity=0 がいけないんじゃないのか?

polarity=1としてみると、動くではないですか。

オシロスコープのCH1:出力波形 CH2:MOSI(SPI Tx)です。

リセットされたところでSIN波に代わり、最後のコマンド(波形設定)で三角波になっているのがわかる。リセットの次に周波数設定されるまでは、波形が出ていないので、周波数レジスタもリセットされていることがわかる。

AD9833 Triangle

waveform()の値は、0-2までの値で設定し、SIN,SQUAR,TRIANGLEの波形となります。

このデバイスは、Si5351Aと異なり面倒は計算が一切必要ないので、わかりやすい構成となっています。

28ビットのレジスタ設定で、フルで25MHzまでを表現しています。

上位、下位のどちらかの14ビットを単独で設定することもできるようです。

ただし、源発信器の25MHz以上の周波数は出せません。

よって50MHzを出すには、高調波を使用することになりそうです。

でもこっちの方が断然使いやすそうなんだけれど・・

 

上記の実験では、下記のコードを使用しました。

 

#AD9833 Raspberrypi pico practice
from machine import SPI, Pin
import time
spi = SPI(0, baudrate=8000000, polarity=1, phase=0, bits=8, firstbit=SPI.MSB,sck=Pin(18),mosi=Pin(19))
cs=Pin(17,Pin.OUT)
#2^14=16384
freq=1000
print(freq)
freq=int(freq/25000000*(2**28))
print('{:0>7x}'.format(freq))
phase=0
ireset=0x0100
noreset=0x0000
set_freq01_cmd=0x2000
freq0_set=0x4000
freq1_set=0x8000
Phase0=0xc000
Phase1=0xe000
#data='{:0>28b}'.format(freq)
def AD9837_write(data):
    cs.value(0)
    spi.write(data.to_bytes(2,"big"))
    cs.value(1)
    time.sleep_us(50)
    
def reset():
    ireset=0x0100
    data=ireset
    AD9837_write(data)

    
def set_freq0(freq):
    set_freq01_cmd=0x2000
    data=set_freq01_cmd
    AD9837_write(data)
    
    freq0_set=0x4000
    freq_msb=int(freq/16384)
    #print('{:0>4x}'.format(freq_msb))
    freq_lsb=freq % 16384
    #print('{:0>4x}'.format(freq_lsb))
    data=int(freq_lsb)+freq0_set
    #print('{:0>4x}'.format(data))
    AD9837_write(data)

    data=int(freq_msb)+freq0_set
    #print('{:0>4x}'.format(data))
    AD9837_write(data)


def set_freq1(freq):
    set_freq01_cmd=0x2000
    data=set_freq01_cmd
    AD9837_write(data)
    
    freq1_set=0x8000
    freq_msb=int(freq/16384)
    freq_lsb=freq % 16384
    
    data=int(freq_lsb)+freq1_set
    AD9837_write(data)
    
    data=int(freq_msb)+freq1_set
    AD9837_write(data)
    


def set_phase0(phase):
    phase0=0xc000
    data=int(phase)+phase0
    AD9837_write(data)
    
def set_phase1(phase):
    phase1=0xe000
    data=int(phase)+phase1
    AD9837_write(data)
    
def noreset():
    ireset=0x0000
    data=ireset
    AD9837_write(data)
    
def waveform(data):
    wav=[0x2000,0x2028,0x2002]
    print(wav[data])
    AD9837_write(wav[data])
    
reset()
set_freq0(freq)
set_freq1(freq)
set_phase0(phase)
set_phase1(phase)
waveform(2)