ja1yaz’s diary

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

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

改めて、データシートを読んでみたところ、ちゃんと書いてありました。

 

AD9833: 低消費電力 20 mW 2.3 〜 5.5 V プログラマブル波形発生器 (analog.com)

 

しかも一番最初のページの特徴の項目に。

「0~12.5MHzの出力周波数レンジ」

でした。

出力電圧については、下記の記述を見つけました。しかもTypical値でした。

VOUT最大 0.65 V
VOUT最小 38 mV

これは文句は言えないな。

しかも中華モジュールだからな。秋月のも買ってみようかな。

にしても、いろいろググってみても、MHzオーダーで動かしている記事が見当たらないんだよな。

以前秋月で売っていた、少々お高いDDSモジュールは、7MHzあたりは余裕で出力できていたのに。ちゃんとしたDDSモジュールを選ばないとだめなのかな。

AD9958BCPZあたりかな?

200ppm/°Cという特性も今一つだしな。

しかし。このお手軽さは、捨てるには惜しい駒だなー。2つも買っちゃったし。

 

気を取り直して、他の機能を試してみることにした。

このデバイスには、Phaseレジスタが二つあり、切り替えて使用できるようだ。

CH1(黄色)がSIN波出力、CH2(緑)がI2Cの波形だ、緑の波形とほぼ同時に位相が90度変化しているのがわかる。位相は、2πラジアンを12ビットで表現している。

Phaseレジスタ1を1024としてみた。

AD9833_Phase_shift

もう少し詳しく見てみると、I2Cのコマンドが発行されて2us以内に位相が変化しているのがわかる。結構反応が速い。

AD9833_Phase_shift_2us

先発のコードに追加して

frq_phase_sel(0,1)
frq_phase_sel(0,0)
frq_phase_sel(0,1)
frq_phase_sel(0,0)

これで、周波数と、Phaseのレジスタの切り替えをするようにしてみた。

実験には下記のコードを使用した。

 

#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=10000

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(5)
    
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=0x00000
    data=ireset
    AD9837_write(data)
    
def waveform(data):
    wav=[0x2000,0x2028,0x2002]
    print(wav[data])
    AD9837_write(wav[data])
def frq_phase_sel(f_res,p_res):
    cmd=int(0x2000+f_res*0x0800+p_res*0x0400)
    AD9837_write(cmd)
    time.sleep_us(100)
    
reset()
set_freq0(freq)
#freq1=2*freq
set_freq1(freq)
set_phase0(phase)
phase1=int(2**10)
set_phase1(phase1)
waveform(0)

frq_phase_sel(0,1)
frq_phase_sel(0,0)
frq_phase_sel(0,1)
frq_phase_sel(0,0)

 

それではと、周波数レジスタの切り替えもやってみた。

10kHzと倍の20kHzで交互に出力してみた。

やはり、周波数が高くなったところは、振幅も変化しているのがわかる。周波数の方は、滑らかに変化している感じだ。

Sweepさせるときは、周波数レジスタを交互に切り替えながらやるべしと書いてあった。こうすることで途切れずにSweepできるようになっているのだろう。

AD9833_Frequency_shift_keying

大分わかってきたような気がする。

 

使用したコードは、ほとんど同じだが、一応書いておく。

frq_phase_sel(1,0)
frq_phase_sel(0,0)
frq_phase_sel(1,0)
frq_phase_sel(0,0)

こんな風に、周波数と、Phaseのレジスタの切り替えを行いやすいようにしてみた。

 

**************以下*******************

#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=10000

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(5)
    
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=0x00000
    data=ireset
    AD9837_write(data)
    
def waveform(data):
    wav=[0x2000,0x2028,0x2002]
    print(wav[data])
    AD9837_write(wav[data])
def frq_phase_sel(f_res,p_res):
    cmd=int(0x2000+f_res*0x0800+p_res*0x0400)
    AD9837_write(cmd)
    time.sleep_us(100)
    
reset()
set_freq0(freq)
freq1=2*freq
set_freq1(freq1)
set_phase0(phase)
phase1=int(2**10)
set_phase1(phase1)
waveform(0)

frq_phase_sel(1,0)
frq_phase_sel(0,0)
frq_phase_sel(1,0)
frq_phase_sel(0,0)