Linux/FreeBSD 用 A/D 変換器(デジタル I/O 付) とデバイスドライバ

PCMCIA の汎用 A/D 変換器のハードウェアと Linux/FreeBSD デバイスドライバの セットです。

1 ハードウェアの特徴

アナログ入力は一部を平衡(differential)、一部を不平衡(singke-ended)という使いか たはできません。同様に、一部をバイポーラ、一部をモノポーラという使い方もできま せん。理由は単一の A/D 変換器を入力部のマルチプレクサで切り替えているためです。

複数の入力チャネルを使うときは、使用する最初と最後のチャネルをプログラムで 指定すると、サンプリング毎に入力チャネルを切り替えてゆき、最後に達すると 最初に戻るという動作になりますので、チャネル毎のサンプリング・レートは 同時に使用するチャネル数に反比例して低下します。

内部メモリは最大 2^15 bit のサイズまで、2^n (n = 8, 9, 10, .. 15) byte の間で プログラムでそのサイズを変更することができ、FIFO モードで使う場合は、 コンピュータ側が追い付く限り、連続変換ができます。トリガ条件を指定できる、 BURST モードについては、最大 16 K サンプルしかできません。トリガレベル、 エッジ/レベルの選択、トリガ波形の方向(POSITIVE/NEGATIVE)はプログラム可能です。

内部メモリに記憶された変換結果は、4 bit のチャネル番号と 12 bit のアナログ データの値から構成されます。

デジタル入力は TTL レベル、デジタル出力は TTL レベルで 4mA の駆動能力 があります。

2 ソフトウェアの特徴

デバイスドライバ、ライブラリ、サンプルプログラムはソースコードのみの供給です。

A/D 変換については、ioctl で変換条件を指定し、read で変換結果を読み込むだけ の簡単なプログラムで使えますが、さらにプログラムを簡略化するために、 入力レンジやトリガ条件を現実の値から DAQ チップの内部形式に変換したり、 変換結果のバイナリデータを現実の数値に変換するための、ライブラリが付属 しています。

3 プログラム例

3.1 single conversion

#include <stdio.h>
#include <sys/ioctl.h>
#include <daqi508.h>

#define BUFSIZE         512

int fd;
char buf[BUFSIZE];

main(argc, argv) char **argv;
{
int conf, i, n;

  if ((fd = open("/dev/daq0", 2)) < 0)
	error("can't open %s", "/dev/daq0");
/* 200kHz sampling, 10V bipolar range, single-ended input channel 0 */
  conf = daq_fifo_setup(fd, 200e3, 10.0, 0, 0, DAQ_BIPOLAR|DAQ_SINGLEEND);
  if ((n = read(fd, buf, 2)) < 0)
	error("read() error.", (char *)0);
  printf("%  g\n", daq_real_val(buf, conf, NULL));
  return close(fd);
}

error(s, t) char *s, *t;
{
  perror("");
  fprintf(stderr, s, t);
  fprintf(stderr, "\n");
  exit(1);
}

3.2 non-triggered one time conversion

#include <stdio.h>
#include <sys/ioctl.h>
#include <daqi508.h>

#define BUFSIZE         32768


nt fd;
char buf[BUFSIZE];

main(argc, argv) char **argv;
{
int conf, i, n;
char *s;

  if ((fd = open("/dev/daq0", 2)) < 0)
	error("can't open %s", "/dev/daq0");
  /* 200kHz sampling, 10V bipolar range, single-ended input channel 0 */
  conf = daq_fifo_setup(fd, 200e3, 10.0, 0, 0, DAQ_BIPOLAR|DAQ_SINGLEEND);
  if ((n = read(fd, buf, 32768)) < 0)
	error("read() error.", (char *)0);
  n /= 2;
  for (i = 0, s = buf; i < n; i++, s += 2)
	printf("%g\n", daq_real_val(s, conf, NULL));
  return close(fd);
}

3.3 non-triggered continuous conversion

#include <stdio.h>
#include <sys/ioctl.h>
#include <daqi508.h>

#define BUFSIZE         32768

int fd;
char buf[BUFSIZE];

main(argc, argv) char **argv;
{
int conf, i, j, n;
char *s;

 if ((fd = open("/dev/daq0", 2)) < 0)
	error("can't open %s", "/dev/daq0");
  /* 20kHz sampling, 10V bipolar range, single-ended input channel 0 */
  conf = daq_fifo_setup(fd, 20e3, 10.0, 0, 0, DAQ_BIPOLAR|DAQ_SINGLEEND);
  for (i = 0; i < 5; i++) {
	if ((n = read(fd, buf, 32769)) < 0)
		error("read() error.", (char *)0);
  else if (n == 0)
	break;
  n /= 2;
  for (j = 0, s = buf; j < n; j++, s += 2)
	printf("%g\n", daq_real_val(s, conf, NULL));
  }
  return close(fd);
}

3.4 triggered conversion

#include <stdio.h>
#include <sys/ioctl.h>
#include <daqi508.h>

#define BUFSIZE         32768

int fd;
char buf[BUFSIZE];

main(argc, argv) char **argv;
{
int conf, i, n;
char *s;

  if ((fd = open("/dev/daq0", 2)) < 0)
	error("can't open %s", "/dev/daq0");
  /* 200kHz sampling, 10.0V bipolar range, single-ended input,
	1 pre-trigger, 0.0V level positive edge trigger */
  conf = daq_trig_setup(fd, 200e3, 10.0, 0, 0, DAQ_BIPOLAR|DAQ_SINGLEEND,
	0.0, 1, 0);
  if ((n = read(fd, buf, 32768)) < 0)
	error("read() error.", (char *)0);
  n /= 2;
  for (i = 0, s = buf; i < n; i++, s += 2)
	printf("%g\n", daq_real_val(s, conf, NULL));
  return close(fd);
}

3.5 DIGITAL I/O

#include <stdio.h>
#include <sys/ioctl.h>
#include <daqi508.h>

int fd;

main(argc, argv) char **argv;
{
  int i;

  if ((fd = open("/dev/daq0", 2)) < 0)
        error("can't open %s", "/dev/daq0");
  /* Configure IOPIN0-3 for outout, IOPIN4-7 for input */
  daq_dir(fd, 0x07);
  for (i = 0; i < 1000; i++) {
        /* output to IOPIN */
        daq_out(fd, (i & 0x0F));
        digital_in();
	sleep(1);
        /* Inout from IOPIN */
        digital_in();
        sleep(1);
        daq_out(fd, ~(i & 0x0F));
        digital_in();
        sleep(1);
  }
  return close(fd);
}

digital_in()
{
  int i, v;

  v = daq_in(fd);
  printf("%02x\n", v);
  printf("DIGITAL INPUT:");
  for (i = 0; i < 8; i++)
        printf(" %d", (v & (0x80 >> i)) ? 1 : 0);
  printf("\n");
}