MCP4726はI2Cで通信制御するD/A変換です。 MCP4726のコマンド覚書▽マニュアルはこちら を参照して下さい。秋月電子の該当ページはこちらにあります。
わかりにくいですが、下の写真の赤矢印で示した白丸が1番ピンです。

回路図は以下の通りです。D/A変換は、VSSからVDDの範囲で行われます。VREFは使いませんでした。 VREFを使う場合は、VSSからVREFの範囲でD/A変換が行われます。ただし、VREF <= VDD でなければなりません。

基本的にはこのモードで書き込めば欲しい電圧を得る事ができます。 出力電圧は12ビット0から4095 (0x000 - 0xFFF)で指定します。 最小限のパラメータ変更によってアナログ出力を手早く更新する時に使います
| 1: | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
| 2: | 0 | 0 | PD1 | PD0 | B11 | B10 | B9 | B8 |
| 3: | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
下のプログラムの場合、書き込んだ2byteで0x800を表しています。
5v × (0x800/0xFFF) ≒ 2.5v が出力されます。
PD0, PD1についてはのコンフィグレーションを参照して下さい。
Wire.setClockは、I2C通信のクロックスピードを設定しています。 このデバイスはファーストモード400kHzにも対応しています。この行がない場合は100kHzの標準モードで動作します。
// include the I2C library:
#include <Wire.h>
void setup() {
// デバイスアドレス(スレーブ)
uint8_t DEVICE_ADDRESS=0x60;
// マスタとしてI2Cバスに接続する
Wire.begin();
Wire.setClock(400000); // I2C First Mode
delay(100);
Wire.beginTransmission(DEVICE_ADDRESS);
Wire.write(B00001000); //0x08 PD==0/PD1=0
Wire.write(B00000000); //0x00
Wire.endTransmission();
}
揮発性の DAC レジスタの値とコンフィグレーション ビットの更新に使います。EEPROM はこのコマンドの影響を受けません。
| 1: | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
| 2: | 0 | 1 | 0 | VREF1 | VREF0 | PD1 | PD0 | G |
| 3: | B11 | B10 | B9 | B8 | B7 | B6 | B5 | B4 |
| 4: | B3 | B2 | B1 | B0 |
揮発性と不揮発性(EEPROM)のDACレジスタの値とコンフィグレーションビットの更新に使います。 不揮発性レジスタは、電源を入れた瞬間に所定の電圧を出したい時に使います。
| 1: | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
| 2: | 0 | 1 | 1 | VREF1 | VREF0 | PD1 | PD0 | G |
| 3: | B11 | B10 | B9 | B8 | B7 | B6 | B5 | B4 |
| 4: | B3 | B2 | B1 | B0 |
以下のプログラムは電源投入時にVDDと同じ電圧を出力する設定です。
// include the I2C library:
#include <Wire.h>
void setup() {
// デバイスアドレス(スレーブ)
uint8_t DEVICE_ADDRESS = 0x60; // B01100000
// マスタとしてI2Cバスに接続する
Wire.begin();
Wire.setClock(400000); // I2C First Mode
delay(100);
Wire.beginTransmission(DEVICE_ADDRESS);
Wire.write(B01100000); //全メモリ書き込み, VREF1/0=0 PD1/0=0 G=0
Wire.write(B11111111); //FFH
Wire.write(B11110000); //F0H
Wire.endTransmission();
}
揮発性コンフィグレーションレジスタビットだけを更新する場合に使います。
| 1: | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
| 2: | 1 | 0 | 0 | VREF1 | VREF0 | PD1 | PD0 | G |
このコマンドは、デバイスの全メモリを読み出します。読み出されるデータは、揮発性と不揮発性 (EEPROM)のDACレジスタの値とコンフィグレーション ビット、揮発性のステータスビットです。
| 1: | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
Wire.requestFrom(DEVICE_ADDRESS, 8);
while(Wire.available()) {
unsigned char c = Wire.read(); // 1バイトを受信
Serial.print(c,HEX);
Serial.print(" ");
}
Serial.println(" ");
受信結果
| 1: | 1 | 1 | 0 | VREF1 | VREF0 | PD1 | PD0 | G |
| 2: | RAM B11-B08 | |||||||
| 3: | RAM B7-B0 | 00 | ||||||
| 4: | E0H | |||||||
| 5: | ROM B11-B08 | |||||||
| 6: | ROM B7-B0 | 00 | ||||||
パワーダウン・ビットと出力抵抗性負荷
| PD1 | PD0 | 動作 |
|---|---|---|
| 0 | 0 | 通常動作 |
| 0 | 1 | 1kΩ抵抗を介してグランドに接続 |
| 1 | 0 | 125kΩ抵抗を介してグランドに接続 |
| 1 | 1 | 640kΩ抵抗を介してグランドに接続 |
ゲイン選択ビット
| G | 動作 |
|---|---|
| 0 | x1 ( ゲイン 1) |
| 1 | 2x ( ゲイン 2)。VRL として VDD を使う場合は適用されません。 |
| VREF = VDD とした場合、デバイスはゲイン選択ビット (G) の設定に関係なくゲイン =x1 のみを使用します。 | |

抵抗ラダー参照電圧 (VRL) 選択ビット
| VREF0 | VREF1 | 動作 |
|---|---|---|
| 0 | x | VDD ( バッファなし ) |
| 0 | 1 | VREF ピン ( バッファなし ) |
| 1 | 0 |
ノコギリ波を発生するサンプルプログラムです。 loopが回る度にregの値をインクリメントしD/A変換に設定しています。
#include <Wire.h> // include the I2C library:
uint8_t DEVICE_ADDRESS = 0x60; // B01100000
void setup() {
Wire.begin(); //Connect I2C bus
Wire.setClock(400000); // I2C First Mode
delay(100);
}
uint16_t reg=0;
void loop() {
Wire.beginTransmission(DEVICE_ADDRESS);
Wire.write((reg>>8)&0x0F);
Wire.write(reg&0xFF);
Wire.endTransmission();
reg++;
reg&=0xFFF;
}
出力波形は以下のようになりました。だいたい0.47secが1周期になります。 0.47secで4096点インクリメントしていますので、だいたい100usecごとにloopが処理されていることがわかります。 ただし、この結果は16MHzで動作しているArduino Microでの結果です。

Arduino Due(84MHz)で同じプログラムを動作させてみました。1周期は0.3secでした。思ったほどは早くなりませんでした。 I2Cという通信方法が遅いためと思われます。
