LoginSignup
0
0

More than 3 years have passed since last update.

初めてのRaspberry Pi Pico ⑱ C言語 12ビットADC MCP3201

Last updated at Posted at 2021-02-20

 Picoには12ビット4チャネルのA-Dコンバータが内蔵されています。もし1チャネル足りなかったら、という想定で外部にICを追加します。

MCP3201のおもなスペック

  • ビット数 12
  • チャネル数 1(疑似差動)
  • 基準電圧 内蔵なし、端子あり
  • 変換速度 100ksps(5V時)
  • インターフェース SPI(モード0,0および1,1)、クロック1.6MHz(5V時)、0.8MHz(2.7V時)
  • 電源動作電圧 2.7~5.5V
  • ピン数 8ピンDIP

接続

 MCP3201は読み出しだけなので、MOSI SPI0 TX(GP3)はつないでいません。

MCP3201の端子 Picoの端子(GPIO) 名称
1 Vref 3V3 3.3V
2 IN+ - -
3 IN- - -
4 Vss GND GND
5 /CS GP5 SPI0 CSn
6 Dout GP4 MISO SPI0 RX
7 CLK GP2 SPI0 SCK
8 Vdd 3V3 3.3V

 入力のIN+/IN-には、電池駆動の簡易電源TL431の出力をつないでいます。約2.5Vです。

プログラムmcp3201.c

 フォルダはmcp3201としました。CMakeLists.txtは省略します。17回以前を参考にしてください。

 MCP3201データシート

 データは読み出しだけです。ダミーの0xffを2回送って、2バイト読み出します。bufferの上位バイトは「? ? 0 D11 D10 D9 D8 D7」が入っているので、0b00011111でマスクします。下位バイトは「D6 D5 D4 D3 D2 D1 D0 D1」と、LSBに余分な1ビットが入っています。16ビットに合成した後、右に1回シフトして捨てています。
 12ビットのデータなので、4096で割って、Vrefの3.3Vをかけて電圧を求めます。Vrefは、できるだけ正確にテスタで測った値を記入しておきます。

/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"

#define PIN_MISO 4
#define PIN_CS   5
#define PIN_SCK  2
#define PIN_MOSI 3

#define SPI_PORT spi0

static inline void cs_select() {
    asm volatile("nop \n nop \n nop");
    gpio_put(PIN_CS, 0);  // Active low
    asm volatile("nop \n nop \n nop");
}

static inline void cs_deselect() {
    asm volatile("nop \n nop \n nop");
    gpio_put(PIN_CS, 1);
    asm volatile("nop \n nop \n nop");
}

int main() {
    stdio_init_all();

    printf("Hello, MCP3201 Reading raw data from registers via SPI...\n");

    // This example will use SPI0 at 0.5MHz.
    spi_init(SPI_PORT, 500 * 1000);
    gpio_set_function(PIN_MISO, GPIO_FUNC_SPI);
    gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);

    // Chip select is active-low, so we'll initialise it to a driven-high state
    gpio_init(PIN_CS);
    gpio_set_dir(PIN_CS, GPIO_OUT);
    gpio_put(PIN_CS, 1);

    // read ADC data. 0xff is dummy. sleep is kiyasume
    uint8_t buffer[2];
    cs_select();
    sleep_ms(1);
    spi_read_blocking(SPI_PORT, 0xff, buffer, 2);
    sleep_ms(1);
    cs_deselect();

    int data = ((buffer[0] & 0b00011111) << 8 | buffer[1]) >> 1;

    // printf(" %d %d \n", buffer[0], buffer[1]);
    // printf(" %b %b \n", (buffer[0] & 0b00011111)<<8, buffer[1]);
    // printf("%b %d \n",data, data);
    printf("ADC is %.3f\n", (3.3 * data) / 4096);

    return 0;
}

 実行結果です。2回目は、入力をショートしています。
ADC101.png

IMGP0249.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0