A-Dコンバータ その4 12ビットSPI MCP3208-(1)
12ビットの分解能をもつMCP3208は、10ビットのMCP3008と同じ16ピンDIPで各機能も同じピン配置です。マスタから送るコマンドのフォーマットも同じですが、読み出すデータ長が異なるので、スケッチはそのままでは流用できません。5Vを基準電圧に使うと、1LSBが 5[V]/2^12=0.00122[V]とアナログ値を細かくディジタルに変換できます。
●MCP3208のおもなスペック
- 分解能 12ビット
- 入力数 シングルエンド;8チャネル、疑似差動;4チャネル
- 動作電圧 2.7~5.5V
- サンプリング速度 100ksps
- クロック 最大2MHz
- 変換方式 逐次変換SAR(Successive Approximation Register)
- 動作時の電流 400uA(5V時)
- 動作温度範囲 -40~85℃
- インターフェース SPI
- パッケージ DIP、SOIC、TSSOP
基準電圧Vref入力、アナログ・グラウンドAGNDとディジタル・グラウンドDGNDが独立した端子で用意されています。
●接続
ノイズ対策のためにVref入力にフィルタを入れる予定です。ほとんど役に立たないかもしれません。電源やVrefに含まれるノイズが1 LSBから10 LSBあると、読み出したデータの下の桁が安定しません。このCRフィルタでは、ノイズがあってもほんのわずかしか抑えられないです。
●読み出しのタイミング
読み出すデータは12ビットです。扱うデータの単位は8ビットなので、最後のビットB0から8ビット単位になるようにさかのぼって数えていきます。8ビット分はB7までです。次のB8から8ビットはB11の前にNullビットと不定の1ビットがあるので、マスタが送っていくるD1ビットまでです。最後は、D2ビットから8ビットになるように0を5個追加します。合計24ビットを、マスタはスレーブのMCP3208へ送ります。
●スケッチ
MCP3208の入力の選択ビットです。シングルエンドのチャネル0は1000になります。マスタが送り出す3バイトのうち1バイト目はD2までの情報なのでb00000110、2バイト目は、D1とD0の00にダミーの000000を加えてb00000000です。3バイト目はすべてダミーなので0x00です。
SGL/ DIFF |
D2 | D1 | D0 | 入力方法 | チャネル |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 疑似差動入力 | CH0→IN+ CH1→IN- |
0 | 0 | 0 | 1 | 疑似差動入力 | CH0→ IN- CH1→IN+ |
0 | 0 | 1 | 0 | 疑似差動入力 | CH2→IN+ CH3→IN- |
0 | 0 | 1 | 1 | 疑似差動入力 | CH2→ IN- CH3→IN+ |
0 | 1 | 0 | 0 | 疑似差動入力 | CH4→IN+ CH5→IN- |
0 | 1 | 0 | 1 | 疑似差動入力 | CH4→ IN- CH5→IN+ |
0 | 1 | 1 | 0 | 疑似差動入力 | CH6→IN+ CH7→IN- |
0 | 1 | 1 | 1 | 疑似差動入力 | CH6→ IN- CH7→IN+ |
1 | 0 | 0 | 0 | シングルエンド | CH0-GND |
1 | 0 | 0 | 1 | シングルエンド | CH1-GND |
1 | 0 | 1 | 0 | シングルエンド | CH2-GND |
1 | 0 | 1 | 1 | シングルエンド | CH3-GND |
1 | 1 | 0 | 0 | シングルエンド | CH4-GND |
1 | 1 | 0 | 1 | シングルエンド | CH5-GND |
1 | 1 | 1 | 0 | シングルエンド | CH6-GND |
1 | 1 | 1 | 1 | シングルエンド | CH7-GND |
読み出した上位バイトは下位4ビットだけが有効なので、0x0fでマスクをします(21行目)。
#include <SPI.h>
#define SS 10
float Vref = 5.0 ;
SPISettings settings(1000000,MSBFIRST,SPI_MODE0);
void setup() {
pinMode(SS, OUTPUT);
Serial.begin(9600);
SPI.begin();
}
void loop(){
SPI.beginTransaction(settings);
digitalWrite(SS, LOW);
SPI.transfer(0b00000110); // Start bit 1 , CH0 singleEnd
byte highByte = SPI.transfer(0b00000000); // CH0 singleEnd
byte lowByte = SPI.transfer(0x00); // dummy
digitalWrite(SS, HIGH);
SPI.endTransaction();
unsigned int dataCh0 = ((highByte & 0x0f) << 8) + lowByte;
float volts = dataCh0*Vref /4096;
Serial.println("highByte= " + String(highByte,DEC) + " lowByte= " + String(lowByte,DEC) );
Serial.println("CH0 " + String(volts,3) + "V");
}
マスタの送っているデータです。
スレーブからのデータです。
コンソールの出力です。CH0は5Vへつないでます。