早速、前に買ってあったSi5351Aをブレッドボードにさしてみた。
Arduinoには、評価用のコードが既にあり、つなげばうまく動作するのだそうだ。
しかし、肝心のI2Cのレベルが、ArduinoUNOは5V系、Si5351Aは3.3V系だ、レベルコンバータチップを間に挟んでみたが、つなぎ方を間違ってあえなくお釈迦に・・・
仕方なく、下の写真のように3.3V系I2CのRaspberrypi Picoを登板させることとなりました。(オシロで見たら、5Vだった。あちゃー なんで動くんだろう)
ググってみると、こちらにもモジュールがそろっているようだった。
しかし、それじゃ何にも楽しくない・・・ということで悩みの始まりです。
このSi5351Aは、内部の設定によりいろいろな周波数を出力できる優れもの、まずは、内部のレジスタの設定値を決定する必要があります。
早速EXCELで計算してみました。MultiSynth0の設定は一定にして、PLLの設定だけで何とかしてみる値を決定しました。
PLLのnの値を3上げると10Hz周波数が上がる計算です。
まずは、直接発振を目指して50MHz近辺の周波数を選んでみました。
以前ちょっと遊んだだけなので、Raspberrypi Picoの何たるかが全く理解できていないところからの出発です。
I2Cの出し方からしてまずよくわかっていないのです。
Byte関数から整数に変換するにもよくわかってないし。
PythonとMicroPythonの違いなどにも結構戸惑っています。
(若干恐れをなして、はやくもDDSチップをポチしてしまった。こっちの方が断然楽そうだな。と)
ってことで
適当にコード(デバッグ中
)を作ってみました。
from machine import Pin, I2C
import time
# I2Cに使うピンの設定です
i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=400000)
# デバイスのアドレスをスキャンします
addr = i2c.scan()
print( "address is :" + str(addr) )
i2c.writeto_mem(96,3,b'\xff')
i2c.writeto_mem(96,16,b'\x80')
i2c.writeto_mem(96,17,b'\x80')
i2c.writeto_mem(96,18,b'\x80')
i2c.writeto_mem(96,19,b'\x80')
i2c.writeto_mem(96,20,b'\x80')
i2c.writeto_mem(96,21,b'\x80')
i2c.writeto_mem(96,22,b'\x80')
i2c.writeto_mem(96,23,b'\x80')
i2c.writeto_mem(96,2,b'\xf0')# set interupt mask
i2c.writeto_mem(96,15,b'\x00')
i2c.writeto_mem(96,183,b'\x80')#XTAL_CL CL=8pf
i2c.writeto_mem(96,149,b'\x00')#SSC disable
#MSNA_p1=2560:18bit
#MSNA_p1_17_16:28_[1:0]=0
#MSNA_p1_15_8:29[7:0]=10
#MSNA_P1_7_0:30[7:0]=0
i2c.writeto_mem(96,28, b'\x00')
i2c.writeto_mem(96,29, b'\x0a')
i2c.writeto_mem(96,30, b'\x00')
#MSNA_P2=0:20bit
#MSNA_P2=0
#MSNA_p2_19_16:31_[3:0]=0
#MSNA_p2_15_8:32[7:0]=0
#MSNA_P2_7_0:33[7:0]=0
i2c.writeto_mem(96,31,b'\x00')
i2c.writeto_mem(96,32,b'\x03')
i2c.writeto_mem(96,33,b'\x00')
#MSNA_p3=625000:20bit
#MSNA_P3=625000
#MSNA_p3_19_16:31_[7:4]=9
#MSNA_p3_15_8:26[7:0]=137
#MSNA_P3_7_0:27[7:0]=104
data=i2c.readfrom_mem(96,31,1)
data=data.hex()
print(data)
data=int(data)
print(data)
data=bin(data << 4)
print(data)
data=int(data)
data=bin(data >> 4)
data=int(data)+9*16
print(data)
i2c.writeto_mem(96,31,bytes([data]))
i2c.writeto_mem(96,26,b'\x89')#
i2c.writeto_mem(96,27,b'\x68')#CLK_0 Enable=1
#MS0_P1=1024:18bit
#MS0_P1_17_16:44[1:0]=0
#MS0_P1_15_8:45[7:0]=4
#MS0_P1_7_0:46[7:0]=0
data=i2c.readfrom_mem(96,44,1)
data=data.hex()
print(data)
data=int(data)
print(data)
data=bin(data >> 2)
print(data)
data=int(data)
data=bin(data << 2)
data=int(data)+0
print(data)
i2c.writeto_mem(96,44,bytes([data]))
i2c.writeto_mem(96,45,b'\x04')
i2c.writeto_mem(96,46,b'\x00')
#MS0_P2=0:20bit
#MS0_P2_19_16:47[3:0]=0
#MS0_P2_15_8:48[7:0]=0
#MS0_P2_7_0:49[7:0]=0
data=i2c.readfrom_mem(96,47,1)
data=data.hex()
print(data)
data=int(data)
print(data)
data=bin(data >> 4)
print(data)
data=int(data)
data=bin(data << 4)
data=int(data)+0
print(data)
i2c.writeto_mem(96,47,bytes([data]))
i2c.writeto_mem(96,48,b'\x00')
i2c.writeto_mem(96,49,b'\x00')
#MS0_P3=1:20bit
#MS0_P3_19_16:47[7:4]=0
#MS0_P3_15_8:42[7:0]=0
#MS0_P3_7_0:43[7:0]=1
data=i2c.readfrom_mem(96,47,1)# 39->47
data=data.hex()
print(data)
data=int(data)
print(data)
data=bin(data << 4)
print(data)
data=int(data)
data=bin(data >> 4)
data=int(data)+0*16
print(data)
i2c.writeto_mem(96,47,bytes([data]))
i2c.writeto_mem(96,42,b'\x00')
i2c.writeto_mem(96,43,b'\x01')
i2c.writeto_mem(96,177,b'\xac')
i2c.writeto_mem(96,16,b'\x4f')
i2c.writeto_mem(96,3,b'\xfe')
適当に描いたコードを走らせて、オシロスコープでアドレス96(0x60)、データ3(0x03)を書き込んだところでトリガをかけてデータをとりこんでみた。
確かにデータ03を書き込んだところから取り込めている。
コードの最後のデータ03を書き込んだところで終わっている。
このことから、データがきちんと遅れていることが確認できた。
下記は、取り込んだI2Cの通信データだ。
Marked | Time | Serial Bus | Restart | Address | Data | Missing Ack |
-174.8us | Serial1 | 60W | 03 FF | |||
-49.60us | Serial1 | 60W | 10 80 | |||
55.20us | Serial1 | 60W | 11 80 | |||
160.8us | Serial1 | 60W | 12 80 | |||
265.6us | Serial1 | 60W | 13 80 | |||
371.6us | Serial1 | 60W | 14 80 | |||
476.0us | Serial1 | 60W | 15 80 | |||
582.0us | Serial1 | 60W | 16 80 | |||
687.2us | Serial1 | 60W | 17 80 | |||
792.4us | Serial1 | 60W | 02 F0 | |||
897.6us | Serial1 | 60W | 0F 00 | |||
1.002ms | Serial1 | 60W | B7 80 | |||
1.107ms | Serial1 | 60W | 95 00 | |||
1.211ms | Serial1 | 60W | 1C 00 | |||
1.316ms | Serial1 | 60W | 1D 0A | |||
1.422ms | Serial1 | 60W | 1E 00 | |||
1.527ms | Serial1 | 60W | 1F 00 | |||
1.632ms | Serial1 | 60W | 20 03 | |||
1.738ms | Serial1 | 60W | 21 00 | |||
1.861ms | Serial1 | 60W | 1F | |||
1.969ms | Serial1 | X | 60R | 0 | X | |
3.658ms | Serial1 | 60W | 1F 90 | |||
3.775ms | Serial1 | 60W | 1A 89 | |||
3.883ms | Serial1 | 60W | 1B 68 | |||
3.998ms | Serial1 | 60W | 2C | |||
4.098ms | Serial1 | X | 60R | 0 | X | |
5.432ms | Serial1 | 60W | 2C 00 | |||
5.543ms | Serial1 | 60W | 2D 04 | |||
5.648ms | Serial1 | 60W | 2E 00 | |||
5.761ms | Serial1 | 60W | 2F | |||
5.862ms | Serial1 | X | 60R | 0 | X | |
7.168ms | Serial1 | 60W | 2F 00 | |||
7.284ms | Serial1 | 60W | 30 00 | |||
7.391ms | Serial1 | 60W | 31 00 | |||
7.503ms | Serial1 | 60W | 2F | |||
7.604ms | Serial1 | X | 60R | 0 | X | |
8.906ms | Serial1 | 60W | 2F 00 | |||
9.024ms | Serial1 | 60W | 2A 00 | |||
9.131ms | Serial1 | 60W | 2B 01 | |||
9.236ms | Serial1 | 60W | B1 AC | |||
9.340ms | Serial1 | 60W | 10 4F | |||
9.445ms | Serial1 | 60W | 03 FE |
しかし、出力は、うんともすんとも言わない状態だ。
データシートのフローのように初期化しているんだけれどもうまく制御できていない。
また壁にぶち当たった感じだ。
ほかの方の初期化方法をググってみたら最後にこのフレーズ「16,b'\x4f'」を入れているのが分かった。
i2c.writeto_mem(96,177,b'\xac')
i2c.writeto_mem(96,16,b'\x4f')
i2c.writeto_mem(96,3,b'\xfe')
としたら
動いた。
計算通り50MHz近辺のサイン波となっているようだ。