Picoには12ビット4チャネルのA-Dコンバータが内蔵されています。ENOB(effective number of bits:有効ビット数)が9.5なので、もう少し高いビット数がほしいという想定で外部にICを追加します。
LTC2461のおもなスペック
- ビット数 16
- チャネル数 1(シングルエンド)
- 基準電圧 内蔵あり1.25V
- 変換レート 60もしくは30回/秒
- インターフェース I2C(最大400kHz)
- スレーブ・アドレス 0x14(デフォルト)
- 動作電圧 2.7~5.5V
- ピン数 12ピンMSOP
接続
MSOPパッケージのLTC2461をDigi-Keyから購入しました。リード線のピッチは0.65mmの12ピンです。秋月電子通商のDIP変換ボードにはんだ付けしてから利用しました。はんだ付けは、こちらを参照ください。
マニュアルに従って、Vcc、REFout、Comp端子からは0.1uFの積層セラミック・コンデンサをGND端子に接続しました。スレーブ・アドレス設定のA0ピンはGNDに落とし、0x14に設定しました。REF-端子はGNDへつなぎました。

|LTC2461の端子| Picoの端子(GPIO) |名称|
|------------|------------|:-------------:|:------|
|1 REFout| -| -|
|2 Comp| -| -|
|3 A0| GND| GND|
|4 GND| GND| GND|
|5 SCL| GP9| SCL|
|6 SDA| GP8| SDA|
|7 GND| GND| GND|
|8 REF-| GND| GND|
|9 IN| -| -|
|10 GND| GND|GND|
|11 GND| GND| GND|
|12 Vcc| 3.3V| 3.3V|
LTC2461の入力には、直流標準電圧電流発生器TR6142で電圧を入力しています。1.0000だと小数点第4位まで正確です。
プログラムLTC2461.c
フォルダ名はLTC2461としました。CMakeLists.txtは省略します。17回以前を参考にしてください。
設定用レジスタのアドレスはありません。
b7 EN1、b6 EN0、b5 SPD、b4 SLP、b3 -、b2 -、b1 -、b0 -
EN1、EN0が'10'で、次の2ビットが有効になります。
SPD;スピード・ビット。SLP;スリープ・ビット
設定時に書き込むデータは、EN1とEN2のイネーブル・ビットはデフォルトの’10’、スピード・ビットSPDはデフォルトの60Hzではなくバックグランド・オフセット較正が行われる30Hzの'1'に変更し、リファレンス電圧をスリープ(SLPビット)させないようにデフォルトの'0'のままにしました。下位4ビットはダミーの'f'とし、0xafを書き込みます。
読み出すレジスタのアドレスはありません。
読み出したデータは2バイトで、0から65535までのデータです。65535はVrefの電圧に相当します。
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
内部の基準電源電圧は1.25Vですが、1.0000V入力に対して少し低めに出ていたので、1.2509とわずかに変更しました。
デバイスの仕様上、読み出したデータは1回前の変換結果です。
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
# include <stdio.h>
# include "pico/stdlib.h"
# include "hardware/i2c.h"
# define I2C_PORT i2c0
# define READ_BIT 0x80
static int addr = 0x14;
static float Vref = 1.2509;
void setup_I2C(){
// This example will use I2C0 on GPIO8 (SDA) and GPIO9 (SCL) running at 100kHz.
i2c_init(I2C_PORT, 100 * 1000);
gpio_set_function(8, GPIO_FUNC_I2C);
gpio_set_function(9, GPIO_FUNC_I2C);
gpio_pull_up(8);
gpio_pull_up(9);
}
static void I2C_read_registers(uint8_t reg, uint8_t *buf, uint16_t len) {
// For this particular device, we send the device the register we want to read
// first, then subsequently read from the device. The register is auto incrementing
// so we don't need to keep sending the register we want, just the first.
reg = reg | READ_BIT;
i2c_write_blocking(I2C_PORT, addr, ®, 1, true);
i2c_read_blocking(I2C_PORT, addr, buf, len, false);
}
static void I2C_write_register(uint8_t reg, uint8_t data) {
uint8_t buf[2];
//buf[0] = reg & 0x7f; // remove read bit as this is a write
buf[0] = reg;
buf[1] = data;
i2c_write_blocking(I2C_PORT, addr, buf, 2, true);
}
int main() {
stdio_init_all();
printf("\nstart\n");
setup_I2C();
uint8_t val = 0xaf;
i2c_write_blocking(I2C_PORT, addr, &val, 1, true);
sleep_ms(100);
uint8_t buffer[2];
i2c_read_blocking(I2C_PORT, addr, buffer, 2, false);
//I2C_read_registers(0x01,buffer,2);
uint16_t temp = (buffer[0]<<8) | buffer[1];
// printf(" 0x%x 0x%x \n", buffer[0], buffer[1]);
// printf(" %d \n", temp);
float V = Vref * temp / 65535;
printf("input: %.5fV\n", V);
return 0;
}
実行結果です。入力電圧は1.0000Vです。何度もResetスイッチを押して再測定しています。
