💾 Archived View for spam.works › mirrors › textfiles › computers › 8chan12b.asc captured on 2023-06-14 at 15:58:35.

View Raw

More Information

-=-=-=-=-=-=-

From: fdeck@happy.helios.nd.edu (francis deck)
Subject: Cheap 12-bit ADC circuit for PC

              CHEAP 12-BIT ADC FOR IBM PC

                   Francis J. Deck
             fdeck@grumpy.helios.nd.edu

This is an 8-channel 12-bit analog-to-digital converter that hooks
up to the parallel printer port of a PC and costs well under $50.
All parts (and data sheets for the chips) are available from
Digi-Key, 1-800-DIGI-KEY.  Recommended construction technique is
hand-wiring on perfboard w/ ground plane.  The big decoupling
caps are mandatory, otherwise you get a lot of noise in the
readings.  The resistors on the inputs limit current through the
input protection diodes of the LTC1290, which protects from
overloads of up to +/- 15 V.

Of course, this circuit is not guaranteed for accuracy, safety,
or reliability, and does not protect your computer against damage
from electric discharge or overloads.  It is up to you to evaluate
the circuit for its suitability for a particular application.

Software is in Turbo Pascal, and was compiled under Version 5.0.
You may have to modify the NLPT and DELAY constants in the program
for your machine.  There is a mandatory 13 microsecond delay which
is created by a software loop.

SCHEMATIC DIAGRAM

                                            8 ----- 14
ANALOG INPUTS                           -----|4 MHz|---P
(+/- 2.5 V)        LTC1290             |     |Clock|7
                1 ---------- 20        |     |Osc  |---G
A0 o------R------|CH0    VCC|----P     |      -----
                2|          |19        |      IBM PC Parallel
A1 o------R------|CH1   ACLK|----------       Printer Port
                3|          |18            2  (use male DB25)
A2 o------R------|CH2   SCLK|---------------o D0
                4|          |17            3
A3 o------R------|CH3    DIN|---------------o D1
                5|          |16           10
A4 o------R------|CH4   DOUT|---------------o ACK
                6|          |15            4
A5 o------R------|CH5    CS'|---------------o D2
                7|          |14           18
A6 o------R------|CH6   REF+|------     G---o GND
                8|          |13    |
A7 o------R------|CH7   REF-|---G  |
                9|          |12    |---R---P
             G---|COM     V-|---N  |+
               10|          |11    Z
             G---|DGND  AGND|---G  |
                  ----------       G

POWER SUPPLY

          +---------+-----------------o +5 V
          |         |
          |      gnd|
          |+      ----- out
          B      |79L05|-----G
          |       -----
          |         |in
          |         |
          +---------+-----------------o -4 V

LEGEND:

     P = +5 V supply
     N = negative supply
     G = ground
     R = 1k resistor
     Z = LM336Z-2.5 precision Zener
     B = 9 V battery

DECOUPLING

     +5 Supply:  22 uF tantalum (watch polarity)
     -4 Supply:  0.1 uF disc
     REF+:  4.7 uF tantalum (watch polarity)}

{======== CONTROL ROUTINES FOR 12-BIT ADC CIRCUIT ========}

unit ltc1290;

interface

{-------- User-definable constants --------}

const
     lpt1 = 1; {these define the 3 printer ports}
     lpt2 = 2;
     lpt3 = 3;

     adc_nlpt = lpt1; {which port?}
     vref = 2.48; {reference voltage}

{-------- Read an ADC channel, result in V --------}

function adc_read (ch: integer): real;

{======== Implementation Section ========}

implementation

const
     sclk = 1; {SCLK line on output port}
     din = 2; {DIN line on output port}
     dout = 64; {DOUT line on output port}
     cs = 4; {CS' line on input port}

var
   lpt_addrlist: array[1..3] of word absolute $40:08; {BIOS RAM}
   aout, ain: word; {input, output port addresses}

{-------- Read an ADC channel --------}

function adc_read;

const
     wconst = 1 + 32 + 64; {setup for single-ended, bipolar,
                            MSB first}

     chconst: array[0..7] of byte = (0,2,8,10,4,6,12,14); {channels}

     delay = 10; {may have to be larger for '386 machines}

var
   i: integer; {loop counter}
   win: word; {word transmitted to ADC chip}
   result: word; {word received from ADC chip}

begin
     for i := 1 to delay do begin end; {software delay}

     win := wconst + chconst[ch];

     {transmit setup word}

     port[aout] := 0; {drop CS'}

     for i := 1 to 12 do begin
         port[aout] := (win and 1)*din; {put bit on output}
         port[aout] := (win and 1)*din + sclk; {clock it out}
         win := win div 2; {shift setup word}
         port[aout] := 0; {drop clock line}
         end;

     port[aout] := cs; {raise CS'}

     for i := 1 to delay do begin end; {software delay}

     {receive conversion result word}

     port[aout] := 0; {drop CS'}

     result := 0;

     win := wconst + chconst[ch]; {retransmit setup word}

     for i := 1 to 12 do begin
         port[aout] := (win and 1)*din; {put bit on output}
         port[aout] := (win and 1)*din + sclk; {clock it out}
         result := result*2; {shift result word}
         if port[ain] and dout <> 0 then result := result + 1;
         port[aout] := 0; {drop clock line}
         end;
     port[aout] := cs; {raise CS'}

     adc_read := vref*((result + 2048) and 4095)/2048 - vref;
     end;

{-------- Initialization ----------}

var
   dummy: real; {dummy analog input}

begin
     aout := lpt_addrlist[adc_nlpt]; {find port addresses}
     ain := aout + 1; {other address}
     port [aout] := cs; {deselect ADC chip}
     dummy := adc_read(0); {read ADC once}
     end.

{======== DEMO PROGRAM FOR ADC =========}

program testltc;

uses
    crt,
    ltc1290;

var
   i: integer;

begin
     writeln ('Press a key to finish.');
     while not keypressed do begin
           for i := 0 to 7 do write (adc_read(i):4:4,' ');
           writeln ('V');
           delay (1000);
           end;
     end.