331 lines
12 KiB
Plaintext
331 lines
12 KiB
Plaintext
|
Using a Printer Port for Simple GPIB/IEEE-488 Operation
|
|||
|
|
|||
|
All programs and documentation, Copyright 1990 by
|
|||
|
|
|||
|
Sydex
|
|||
|
P.O. Box 5700
|
|||
|
Eugene, OR 97405
|
|||
|
Voice: (503) 683-6033
|
|||
|
FAX: (503) 683-1622
|
|||
|
Data: (503) 683-1385
|
|||
|
|
|||
|
All Rights Reserved.
|
|||
|
|
|||
|
INTRODUCTION
|
|||
|
|
|||
|
A while back (quite a while, actually) we had a need for the use
|
|||
|
of a color plotter for some 1-2-3 spreadsheet graphs that we were
|
|||
|
doing. A friend offered us the use of his HP 7470--but there was
|
|||
|
a catch. It seems that the thing had the HPIB/GPIB/IEEE-488
|
|||
|
interface, not a straight serial or parallel connection.
|
|||
|
|
|||
|
This posed a problem. A GPIB card for a PC would set us back
|
|||
|
about $350--and there was no guarantee that 1-2-3 could even talk
|
|||
|
to the thing.
|
|||
|
|
|||
|
I recalled that the old Commodore Pet, as well as the Victor 9000
|
|||
|
and the Osborne I could do a limited amount of GPIB interfacing
|
|||
|
with their parallel ports--so why not a PC? I even had an extra
|
|||
|
port that I wasn't using.
|
|||
|
|
|||
|
After looking at the IBM Tech Reference manual, I discovered that
|
|||
|
there's a problem with this. Although the IBM Parallel Printer
|
|||
|
adapter bills itself as being bi-directional (input and output),
|
|||
|
it's hard-wired for output mode only! Now, I probably could
|
|||
|
drive the plotter with an output-only port, but this was
|
|||
|
aesthetically unsatisfying. How could the parallel port be wired
|
|||
|
to be REALLY bi-directional?
|
|||
|
|
|||
|
The offending item appeared to be the 74LS374 IC used as the data
|
|||
|
output latch--the Output Enable (OE*) pin was grounded (wired
|
|||
|
active). However, there was a spare bit (bit 5) available on the
|
|||
|
74LS174 6-bit latch used to control the printer handshaking
|
|||
|
lines. The solution was obvious--wire the unused bit to Output
|
|||
|
Enable on the LS374--viola!
|
|||
|
|
|||
|
Incidentally, if you're using an IBM PS/2, ignore the next
|
|||
|
section, IBM finally came to its senses and implemented the same
|
|||
|
change when it brought the PS/2 out--you can use the software
|
|||
|
that accompanies this documentation will operate with no changes.
|
|||
|
|
|||
|
ALTERING A PARALLEL ADAPTER
|
|||
|
|
|||
|
Once again, note that this applies to PC XT- and AT- type
|
|||
|
computers (ISA bus) only. If you've got a PS/2, your changed
|
|||
|
parallel port is standard equipment.
|
|||
|
|
|||
|
I'll discuss what has to be done to the simple $15.00 born-in-
|
|||
|
Taiwan parallel adapter, but note that these changes can be made
|
|||
|
to most other parallel adapters that use generic LSTTL IC's.
|
|||
|
This category also includes a number of monochrome display
|
|||
|
adapters.
|
|||
|
|
|||
|
You should know one end of a soldering iron from another; a short
|
|||
|
length of wire-wrap or other small-gauge wire and an X-acto or
|
|||
|
other hobbyist utility knife is useful. The change is simple and
|
|||
|
will take you about 15 minutes (assuming your iron is hot).
|
|||
|
|
|||
|
Most inexpensive parallel-only adapters come from the same basic
|
|||
|
design--12 SSI IC's on a half-slot card.
|
|||
|
|
|||
|
First, locate the 74LS374 IC adjacent to the printer connector on
|
|||
|
the rear of the board. Note that one end of the IC has a
|
|||
|
recessed notch on one end. Also locate the 74LS174 just above
|
|||
|
it. Note the pin numbering:
|
|||
|
|
|||
|
|
|||
|
74LS374 74LS174
|
|||
|
|
|||
|
+-U-+ +-U-+
|
|||
|
Pin 1 [| |] Pin 20 Pin 1 [| |] Pin 16
|
|||
|
Pin 2 [| |] Pin 19 Pin 2 [| |] Pin 15
|
|||
|
Pin 3 [| |] Pin 18 Pin 3 [| |] Pin 14
|
|||
|
Pin 4 [| |] Pin 17 Pin 4 [| |] Pin 13
|
|||
|
Pin 5 [| |] Pin 16 Pin 5 [| |] Pin 12
|
|||
|
Pin 6 [| |] Pin 15 Pin 6 [| |] Pin 11
|
|||
|
Pin 7 [| |] Pin 14 Pin 7 [| |] Pin 10
|
|||
|
Pin 8 [| |] Pin 13 Pin 8 [| |] Pin 9
|
|||
|
Pin 9 [| |] Pin 12 +---+
|
|||
|
Pin 10 [| |] Pin 11
|
|||
|
+---+
|
|||
|
|
|||
|
Remembering that the pin numbering becomes "mirrored", turn the
|
|||
|
board over and locate pin 1 of the 74LS374. Note that it is
|
|||
|
connected by an enlargement of the solder pad to the wide ground
|
|||
|
trace above it. Being careful not to sever the wide ground
|
|||
|
trace, take your knife and separate the pin 1 pad from the ground
|
|||
|
trace. Check your work with a continuity tester.
|
|||
|
|
|||
|
Next, locate pin 7 on the 74LS174. Take a short piece of wire
|
|||
|
and connect pin 1 on the 74LS374 to this pin. Be neat and check
|
|||
|
your work.
|
|||
|
|
|||
|
That's it! Your card will still function normally as a printer
|
|||
|
adapter, but now has a true bi-directional mode of operation.
|
|||
|
|
|||
|
BUILDING A CABLE
|
|||
|
|
|||
|
The next task is to build a cable from the 25-pin parallel
|
|||
|
printer connection to a 24-pin male GPIB connector.
|
|||
|
Unfortunately, some "criss-crossing" of connections is necessary
|
|||
|
between the two, so you can either solder up a multiconductor
|
|||
|
cable between a male solder-cup DB25P connector and a 24 pin
|
|||
|
"Blue Ribbon" connector, or you can do what I did.
|
|||
|
|
|||
|
I took a length of 24-conductor ribbon cable and crimped a male
|
|||
|
DP25P IDC connector on one end and a male 24 pin "centronics"
|
|||
|
connector (Scotch No. 3548, for example) on the other end. I
|
|||
|
then took an inexpensive solder-type DB25 "breakout box" (cost:
|
|||
|
about $7.50) and performed my "wire weaving" in it.
|
|||
|
|
|||
|
In any case, you'll have to make sure the wiring works out this
|
|||
|
way:
|
|||
|
|
|||
|
|
|||
|
GPIB Pin Signal Name DB-25
|
|||
|
======== =========== =====
|
|||
|
|
|||
|
1 -DATA 1 2
|
|||
|
2 -DATA 2 3
|
|||
|
3 -DATA 3 4
|
|||
|
4 -DATA 4 5
|
|||
|
5 -EOI 13
|
|||
|
6 -DAV 1
|
|||
|
7 -NRFD 16
|
|||
|
8 -NDAC 17
|
|||
|
9 -IFC 10
|
|||
|
10 -SRQ 15
|
|||
|
11 -ATN 14
|
|||
|
12 GND 18
|
|||
|
13 -DATA 5 6
|
|||
|
14 -DATA 6 7
|
|||
|
15 -DATA 7 8
|
|||
|
16 -DATA 8 9
|
|||
|
17 -REN 12
|
|||
|
18 GND 19
|
|||
|
19 GND 20
|
|||
|
20 GND 21
|
|||
|
21 GND 22
|
|||
|
22 GND 23
|
|||
|
23 GND 24
|
|||
|
24 GND 25
|
|||
|
|
|||
|
Check your work for accuracy!
|
|||
|
|
|||
|
THE SOFTWARE
|
|||
|
|
|||
|
We've supplied the source and object for a set of "C"-callable
|
|||
|
routines to manage the GPIB interface. We use Microsoft "C" and
|
|||
|
Microsoft MASM, though there should be no reason why this
|
|||
|
wouldn't also work with Borland's Turbo "C" and TASM. Note that
|
|||
|
we make use of the "small" memory model--you could alter this to
|
|||
|
use the huge, large or compact models by making sure that full
|
|||
|
segment-offset addresses are handled and the necessary segment
|
|||
|
register juggling is done.
|
|||
|
|
|||
|
Similarly, there's no reason that the package couldn't be modifed
|
|||
|
to work with BASIC or FORTRAN with appropriate changes.
|
|||
|
|
|||
|
The source file is the file "GPIB_C.ASM" and is written in
|
|||
|
8086 assembly language. These are the routines that are included
|
|||
|
in it:
|
|||
|
int GPIB_Init( int io_port, int our_address)
|
|||
|
|
|||
|
Initializes the GPIB interface. "io_port" is the address
|
|||
|
of the printer adapter being used--usually 0x378 for the
|
|||
|
first and 0x278 for the second. If your adapter is part
|
|||
|
of a monochrome display adapter, its address is 0x3bc.
|
|||
|
"Our_address" is the GPIB talker/listener address that
|
|||
|
the PC is to consider to be its own.
|
|||
|
|
|||
|
The interface is initialized; if no response can be had,
|
|||
|
a status of -1 is returned; a return of 0 signifies no
|
|||
|
error.
|
|||
|
|
|||
|
int GPIB_Send( int listen, char what)
|
|||
|
|
|||
|
This routine sends a single character to the GPIB device
|
|||
|
addressed by "listen". If this function returns -1,
|
|||
|
there's a problem, otherwise the return value is 0.
|
|||
|
|
|||
|
int GPIB_PutStr( int listen, char *string, int count)
|
|||
|
|
|||
|
This routine sends a string of bytes to the GPIB device
|
|||
|
addressed by "listen". "count" bytes are sent. Returns
|
|||
|
are -1 for failure, 0 for success.
|
|||
|
|
|||
|
int GPIB_Stat(void);
|
|||
|
|
|||
|
Simply returns the value of the GPIB status lines.
|
|||
|
These are encoded in the lower 8 bits of the return
|
|||
|
value as:
|
|||
|
|
|||
|
IFC REN EOI SRQ NDAC NRFD ATN DAV
|
|||
|
|
|||
|
|
|||
|
int GPIB_Get( int listen)
|
|||
|
|
|||
|
Reads a character from the GPIB device addressed by
|
|||
|
"listen". Returns the character or -1 if error.
|
|||
|
|
|||
|
int GPIB_GetStr( int listen, char *buf)
|
|||
|
|
|||
|
Reads a string of data from the device addressed by
|
|||
|
"listen". Returns the number of bytes read into "buf"
|
|||
|
or -1 if error.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
int GPIB_SerPoll( int listen)
|
|||
|
|
|||
|
Executes a Serial Poll on the device at "listen".
|
|||
|
Returns the serial poll status in the lower 8 bits of
|
|||
|
the return value or -1 if error.
|
|||
|
|
|||
|
|
|||
|
int GPIB_PutAdd( char what)
|
|||
|
|
|||
|
GPIB primitive. Puts the value "what" out as an address
|
|||
|
byte. Returns 0 if success or -1 if failure.
|
|||
|
|
|||
|
int GPIB_PutData( char what)
|
|||
|
|
|||
|
GPIB primitive. Puts the value "what" out as a data
|
|||
|
byte. Returns 0 if success or -1 if failure.
|
|||
|
|
|||
|
int GPIB_GetData(void);
|
|||
|
|
|||
|
GPIB primitive. Reads the value on the GPIB bus as a
|
|||
|
data value and returns it or -1 if failure.
|
|||
|
|
|||
|
As an example of usage, a terminate-and-stay-resident program,
|
|||
|
LPPLOT, is included to talk to an HP 7470 plotter disguised as
|
|||
|
LPT3. It works--but note that the GPIB version of the 7470 lacks
|
|||
|
arc and circle-drawing HPGL extensions.
|
|||
|
|
|||
|
MISCELLANY
|
|||
|
|
|||
|
Clearly, this scheme represents a way to get by on the cheap.
|
|||
|
This method will not support all GPIB functions, nor is it likely
|
|||
|
to be able to drive more than one GPIB device at a time--the
|
|||
|
output current drive capability just isn't there.
|
|||
|
|
|||
|
If I had it to do over again, I'd change the way I wired the
|
|||
|
cable and wire the ATN signal to pin 10 on the DB25 so that I
|
|||
|
could use the interrupt capability on the printer card to service
|
|||
|
asynchronous requests such as Parallel Poll.
|
|||
|
|
|||
|
But the thing does work--and with a little work, 2 PC's could be
|
|||
|
coupled to do full 8-bit transfers in either direction. Current
|
|||
|
printer port data transfer schemes "nibble" the data, rather than
|
|||
|
use the full data bus width.
|
|||
|
|
|||
|
USAGE AND LICENSING
|
|||
|
|
|||
|
License is hereby granted by Sydex for single-use non-commercial
|
|||
|
application of this code. Contact Sydex for commercial use and
|
|||
|
system-integration licensing rights. Any other use of this code
|
|||
|
or documentation is hereby prohibited without explicit written
|
|||
|
permission from Sydex.
|
|||
|
|
|||
|
|
|||
|
Text and programs by Chuck Guzis
|
|||
|
|
|||
|
Certain products and terms referred to in this document are
|
|||
|
property of the following firms:
|
|||
|
|
|||
|
Hewlett-Packard Corporation, International Business Machines,
|
|||
|
Microsoft Corporation, Borland International, Centronics,
|
|||
|
ITT-Cannon, 3M Corporation.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|