初めてのRaspberry Pi Pico ㉓ C言語 16ビットADC LTC2461 

　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変換ボード](https://akizukidenshi.com/catalog/g/gP-10499/)にはんだ付けしてから利用しました。はんだ付けは、[こちらを参照](https://www.denshi.club/parts/2017/12/127mm065mmic.html)ください。
　マニュアルに従って、Vcc、REFout、Comp端子からは0.1uFの積層セラミック・コンデンサをGND端子に接続しました。スレーブ・アドレス設定のA0ピンはGNDに落とし、0x14に設定しました。REF-端子はGNDへつなぎました。


<img width="220" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/c1da8108-33c1-6d98-97f8-510a64f4b208.png">



|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回以前を参考にしてください。

 　[LTC2461データシート](https://www.analog.com/media/en/technical-documentation/data-sheets/24613fa.pdf)

　設定用レジスタのアドレスはありません。

　　``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回前の変換結果です。


```cpp
/**
 * 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, &reg, 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スイッチを押して再測定しています。

<img width="170" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/5469aa68-3789-228c-3cd7-931bdf8b95f9.png">