改めて、データシートを読んでみたところ、ちゃんと書いてありました。
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としてみた。
もう少し詳しく見てみると、I2Cのコマンドが発行されて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できるようになっているのだろう。
大分わかってきたような気がする。
使用したコードは、ほとんど同じだが、一応書いておく。
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)