textfiles/computers/8chan12b.asc

206 lines
5.9 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.