MCP4726のソースの書き方について

解決


ふぁる  2021-02-28 14:05:23  No: 149600  IP: [192.*.*.*]

既にワッキー様が質問されていたので重複しますが
私も
    Wire.write((value >> 8) & 0x0F);
    Wire.write(value);
の部分で苦悩中です。
papy様のご教授も何度も読み返しましたが、
データシートのどの部分を注視すればいいのかも曖昧です。
Wire.writeについてはArduino 日本語リファレンスにて
送信するデータをキューに入れるのだと雰囲気程度の理解度です。

16進数のvalueを8個右シフトして0x0Fを加えたものを送信。
さらにもう一度valueを送信。

このような処理を行っているのかなぁと漠然としています。
ご教授お願いいたします。

編集 削除
ふぁる  2021-03-01 03:03:14  No: 149601  IP: [192.*.*.*]

少し進展したので追記です。
Wire.write((value >> 8) & 0x0F); //Wire.write(register)デバイスのレジスタを指定
Wire.write(value);                          //Wire.write(value)レジスタにデータを書き込み
このように記述されているのだと思います。
デバイスのレジスタを指定する考え方がわかりません。
皆様ご協力お願いいたします。

編集 削除
papy  2021-03-01 07:07:50  No: 149602  IP: [192.*.*.*]

2017年08月23日の記事なので完全に忘れてますが、

15:  uint16_t value = 4096 / 2; // (0-4095)
16:  Wire.beginTransmission(DEVICE_ADDRESS);
17:    Wire.write((value >> 8) & 0x0F);
18:    Wire.write(value);
19:  Wire.endTransmission();

MCP4726は12ビットD/A変換モジュールなので
・17行目で4bit出力
・18行目で8bt出力
で合計12bitの出力をしていたと思います。

<計算方法>
value = 4096/2 = 2048 = 1000 0000 0000 = 12bit

17行目
value >> 8 = 0000 0000 1000
0000 0000 1000 & 0x0F(1111) = 1000

結果
Wire.write(0000 1000);

18行目
value = 1000 0000 0000

結果
Wire.write(0000 0000);

データシートのp41、p42辺りの
Config Bits、DAC Register Valueが記載されていますが、
17行目の上位4bitは0000の為、何かの設定はデフォルトになっていると思われます。

確認してみました。
p49にWrite Volatile DAC Register Commandだと「PD1:PD0 only」(Power bits Down bits)と書かれています。
p50をみると上位4bit中の上位2bitは00がデフォルトで下位2bit(PD1:PD0)が00の場合は「Not Powered Down (Normal operation)」とあります。なので上位4bitは0000で良いと思われます。

間違っているかもしれませんので詳細はデータシートをご確認ください。
https://akizukidenshi.com/download/ds/microchip/MCP4726.pdf

あんまり覚えてなくてすみませんです。

編集 削除
papy  2021-03-01 07:34:24  No: 149603  IP: [192.*.*.*]

18行目  Wire.write(value);
についてですが、C言語で実験すると次のようになります。

// 次の型は同じ
unsigned char = byte = uint8_t = 0から255まで

// 実験
int main(void){
    unsigned char xxx = 300;
    
    printf("%d", xxx);
}

結果は「44」が表示されます。

300 = 1 0010 1100
44  =   0010 1100


編集 削除
ふぁる  2021-03-01 11:56:01  No: 149604  IP: [192.*.*.*]

papy様、回答ありがとうございます。

詳細な計算方法も教えて頂き、感謝です。

ただ自分の知識の浅さのため、より頭が混乱しています。

17行目で4bit出力
18行目で8bit出力

の件ですが、17行目、18行目はmcp4726に対して何のデータを送って
いるのでしょうか
右シフトや0x0Fの論理積は何故必要なのか

色々と検索中に下記のサイトを参照しました。
ttp://rephtone.com/electronics/arduino-i2c/#outline__2_3
それによると

Slaveデバイスにはレジスタアドレスが存在し場合によって指定する必要がある
Wire.beginTransmission(address);  //接続するIC2デバイスを選択
Wire.write(register);  //I2Cデバイスのレジスタを指定
Wire.write(value);  //レジスタにデータを書き込み
Wire.endTransmission();  //送信を完了

等の記述がありました。
他の方のホームページを参照など、失礼かと失礼かと存じますが
ご回答お願い致します。

編集 削除
papy  URL  2021-03-01 12:49:49  No: 149605  IP: [192.*.*.*]

正確には
17行目 Wire.write(2進数で0000 1000); // 1バイト(8bit)
18行目 Wire.write(2進数で0000 0000); // 1バイト(8bit)

で合計2バイトを送信しています。並べると次のようになります。

0000 1000 0000 0000

このうち上位ビット(左から)から次のような役割になっています。
---
2bits   Command bits
2bits   Power bits Down bits
12bits  Data bits ※12bit = 4096種類
----
合計16bit = 2バイト

データシートの50ページに英語で書かれています。
私は英語はできませんので翻訳しながら確認してます。

編集 削除
papy  2021-03-01 13:09:42  No: 149606  IP: [192.*.*.*]

4096 / 2 = 2048

この2048は2進数にすると次の12bitになります。
1000 0000 0000

MCP4726は「12ビットD/A変換モジュール」なので12bitを使います。

そして、制御用に先頭に0000を足せば
0000 1000 0000 0000
となります。

この2バイト(16bit)を送信する為の処理が17/18行目です。

編集 削除
ふぁる  2021-03-02 09:07:07  No: 149607  IP: [192.*.*.*]

papy 様
大変親切に御回答いただき、ありがとうございました。
今後もこのデバイスを使用するので感謝感謝です。

編集 削除