<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0061)http://et.nmsu.edu/~etti/fall96/computer/printer/printer.html -->
<!
REQUEST: REVIEW
TITLE: Use of a PC Printer Port for Control and Data Acquisition
AUTHOR: Peter H. Anderson
EMAIL ADDRESS: pha@eng.morgan.edu
INDEX:
ORGANIZATION: Morgan State University
<HTML><HTML><HEAD><TITLE>Use of a PC Printer Port for Control and Data Acquisition</TITLE>
<META content="text/html; charset=big5" http-equiv=Content-Type>
<META content="MSHTML 5.00.2314.1000" name=GENERATOR></HEAD>
<BODY bgColor=#ffffff>
<CENTER>link to <a href="http://et.nmsu.edu/~etti" rel='nofollow' onclick='return false;'><I>the <B>Technology
Interface </I></B></A><BR><B>the Electronic Journal for Engineering
Technology</B> </CENTER>
<P><FONT size=2><a href="http://et.nmsu.edu/~etti" rel='nofollow' onclick='return false;'><I>the <B>Technology
Interface</B></A> /Fall 96</I></FONT>
<CENTER>
<HR>
<H1>Use of a PC Printer Port for Control and Data Acquisition</H1></CENTER>
<HR>
<CENTER>
<H4>by</H4>
<P><B>Peter H. Anderson<BR><I><a
href="mailto:pha@eng.morgan.edu" rel='nofollow' onclick='return false;'>pha@eng.morgan.edu</A></I><BR>Department of
Electrical Engineering<BR>Morgan State University</B><BR></CENTER>
<P>
<P><B>Abstract:</B> <I>A PC printer port is an inexpensive and yet powerful
platform for implementing projects dealing with the control of real world
peripherals. The printer port provides eight TTL outputs, five inputs and four
bidirectional leads and it provides a very simple means to use the PC interrupt
structure.
<P>This article discusses how to use program the printer port. A larger manual
which deals with such topics as driver circuits, optoisolators, control of DC
and stepping motors, infrared and radio remote control, digital and analog
multiplexing, D/A and A/D is avaialable. See
<P>http://www.access.digex.net/~pha
<P>A special thanks to Morgan State University students Towanda Malone,
Christine Samuels and H. Paul Roach for their technical contributions and to New
Mexico State University student Kyle Quinnell for preparing the html file.</I>
<P>
<CENTER>
<H2>I. Printer Port Basics</H2></CENTER>
<P>
<CENTER>
<H3>A. Port Assignments</H3></CENTER>
<P>Each printer port consists of three port addresses; data, status and control
port. These addresses are in sequential order. That is, if the data port is at
address 0x0378, the corresponding status port is at 0x0379 and the control port
is at 0x037a.
<P>The following is typical.
<P><PRE><B>
Printer Data Port Status Control</B>
LPT1 0x03bc 0x03bd 0x03be
LPT2 0x0378 0x0379 0x037a
LPT3 0x0278 0x0279 0x027a
</PRE>
<P>My experience has been that machines are assigned a base address for LPT1 of
either 0x0378 or 0x03bc.
<P>To definitively identify the assignments for a particular machine, use the
DOS debug program to display memory locations 0040:0008. For example:
<P><PRE>
>debug
-d 0040:0008 L8
0040:0008 78 03 78 02 00 00 00 00
</PRE>
<P>Note in the example that LPT1 is at 0x0378, LPT2 at 0x0278 and LPT3 and LPT4
are not assigned.
<P>Thus, for this hypothetical machine;
<P><PRE><B>
Printer Data Port Status Control</B>
LPT1 0x0378 0x0379 0x037a
LPT2 0x0278 0x0279 0x027a
LPT3 NONE
LPT4 NONE
</PRE>
<P>An alternate technique is to run Microsoft Diagnostics (MSD.EXE) and review
the LPT assignments.
<P>
<CENTER>
<H3>B. Outputs</H3></CENTER>
<P>Please refer to the figures titled Figure #1 - Pin Assignments and Figure #2
- Port Assignments. These two figures illustrate the pin assignments on the 25
pin connector and the bit assignments on the three ports.
<HR>
<CENTER>
<P><B>Fig 1. Pin Assignments</B></CENTER>
<HR>
<CENTER>
<P><B>Fig 2. Port Assignments</B></CENTER>
<HR>
<P>Note that there are eight outputs on the Data Port (Data 7(msb) - Data 0) and
four additional outputs on the low nibble of the Control Port. /SELECT_IN, INIT,
/AUTO FEED and /STROBE.
<P>[Note that with /SELECT_IN, the "in" refers to the printer. For normal
printer operation, the PC exerts a logic zero to indicate to the printer it is
selected. The original function of INIT was to initialize the printer, AUTO FEED
to advance the paper. In normal printing, STROBE is high. The character to be
printed is output on the Data Port and STROBE is momentarily brought low.]
<P>All outputs on the Data Port are true logic. That is, writing a logic one to
a bit causes the corresponding output to go high. However, the /SELECT_IN,
/AUTOFEED and /STROBE outputs on the Control Port have inverted logic. That is,
outputting a logic one to a bit causes a logic zero on the corresponding output.
This adds some complexity in using the printer port, but the fix is to simply
invert those bits using the exclusive OR function prior to outputting.
<P>[One might ask why the designers of the printer port designed the port in
this manner. Assume you have a printer with no cable attached. An open usually
is read as a logic one. Thus, if a logic one on the SELECT_IN, AUTOFEED and
STROBE leads meant to take the appropriate action, an unconnected printer would
assume it was selected, go into the autofeed mode and assume there was data on
the outputs associated with the Data Port. The printer would be going crazy when
in fact it wasn't even connected. Thus, the designers used inverted logic. A
zero forces the appropriate action.]
<P>Returning to the discussion of the Control Port, assume you have a value val1
which is to be output on the Data port and a value val2 on the Control port: <PRE>
#define DATA 0x03bc
#define STATUS DATA+1
#define CONTROL DATA+2
...
int val1, val2;
...
val1 = 0x81; /* 1000 0001 */ /* Data bits 7 and 0 at one */
outportb(DATA, val1);
val2 = 0x08; /* 0000 1000 */
outportb(CONTROL, VAL2^0x0b);
/* SELECT_IN = 1, INIT = 0, /AUTO_FEED = 0, /STROBE = 0 */
</PRE>
<P>Note that only the lower nibble of val2 is significant. Note that in the last
line of code, /SELECT_IN, /AUTO_FEED and /STROBE are output in inverted form by
using the exclusive-or function so as to compensate for the hardware inversion.
<P>For example; if I intended to output 1 0 0 0 on the lower nibble and did not
do the inversion, the hardware would invert bit 3, leave bit 2 as true and
invert bits 1 and 0. The result, appearing on the output would then be 0 0 1 1
which is about as far from what was desired as one could get. By using the
exclusive-or function, 1 0 0 0 is actually sent to the port as 0 0 1 1. The
hardware then inverts bits 3, 1 and 0 and the output is then the desired 1 0 0
0.
<P>
<CENTER>
<H3>C. Inputs</H3></CENTER>
<P>Note that in the diagram showing the Status Port there are five status leads
from the printer. (BSY, /ACK, PE (paper empty), SELECT, /ERROR).
<P>[The original intent in the naming of most of these is intuitive. A high on
SELECT indicates the printer is on line. A high on BSY or PE indicates to the PC
that the printer is busy or out of paper. A low wink on /ACK indicates the
printer received something. A low on ERROR indicates the printer is in an error
condition.]
<P>These inputs are fetched by reading the five most significant bits of the
status port.
<P>However, the original designers of the printer interface circuitry, inverted
the bit associated with the BSY using hardware. That is,