⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 use of a pc printer port for control and data acquisition.htm

📁 C 语言的并口控制参考资料.有参考程序,老大,为什么非得要20个字,害得我废话一大堆.
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<!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"><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"><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">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>    
	&gt;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><IMG 
src="Use of a PC Printer Port for Control and Data Acquisition.files/PHAFIG1.gif"> 

<P><B>Fig 1. Pin Assignments</B></CENTER>
<HR>

<CENTER><IMG 
src="Use of a PC Printer Port for Control and Data Acquisition.files/PHAFIG2.gif"> 

<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, when a zero is present 
on input BSY, the bit will actually be read as a logic one. Normally, you will 
want to use "true" logic, and thus you will want to invert this bit. 
<P>The following fragment illustrates the reading the five most significant bits 
in "true" logic. <PRE>    
	#define DATA 0x03bc      
	#define STATUS DATA+1      
	...      
	unsigned int in_val;      
	...      
	in_val = ((inportb(STATUS)^0x80) &gt;&gt; 3);    
</PRE>
<P>Note that the Status Port is read and the most significant bit, corresponding 
to the BSY lead is inverted using the exclusive-or function. The result is then 
shifted such that the upper five bits are in the lower five bit positions. <PRE>    
	0 0 0 BUSY /ACK PE SELECT /ERROR     
</PRE>
<P>Another input, IRQ on the Status Port is not brought to a terminal on the 
DB-25 printer port connector. I have yet to figure out how to use this bit. 
<P>At this point, you should see that, at a minimum, there are 12 outputs; eight 
on the Data Port and four on the lower nibble of the Control Port. There are 
five inputs, on the highest five bits of the Status Port. Three output bits on 
the Control Port and one input on the Status Port are inverted by the hardware, 
but this is easily handled by using the exclusive-or function to selectively 
invert bits. 
<P>
<CENTER>
<H3>D. Simple Example</H3></CENTER>
<P>Refer to the figure titled Figure #3 - Typical Application showing a normally 
open push button switch being read on the BUSY input (Status Port, Bit 7) and an 
LED which is controlled by Bit 0 on the Data Port. A C language program which 
causes the LED to flash when the push-button is depressed appears below. Note 
that an output logic zero causes the LED to light. 
<P><PRE>     
	/* File LED_FLSH.C     
	**     
	** Illustrates simple use of printer port.  When switch is     
	** depressed LED flashes.  When switch is not depressed, LED is     
	** turned off.     
	**     
	** P.H. Anderson, Dec 25, '95     
	*/     
	     
	#include &lt;stdio.h&gt;     
	#include &lt;dos.h&gt;   /* required for delay function */     
	     
	#define DATA 0x03bc     
	#define STATUS DATA+1     
	#define CONTROL DATA+2     
	     
	void main(void)     
	{     
	   int in;     
	   while(1)     
	   {     
	      in = inportb(STATUS);     
	      if (((in^0x80)&amp;0x80)==0)     
	      /* if BUSY bit is at 0 (sw closed) */     
	      {     
	         outportb(DATA,0x00);   /* turn LED on */     
	         delay(100);     
	         outportb(DATA, 0x01);   /* turn it off */     
	         delay(100);     
	      }     
	      else     
	      {     
	         outportb(DATA,0x01);     
	         /* if PB not depressed, turn LED off */     
	      }     
	   }     
	}     
</PRE>
<HR>

<CENTER><IMG 
src="Use of a PC Printer Port for Control and Data Acquisition.files/PHAFIG3.gif"> 

<P><B>Fig 3 Printer Port - Typical Application</B></CENTER>
<P><B>Circuit Description:</B> Logic 1 on output DATA 0 (Data Port - Bit 0) 
causes LED to be off. Logic 0 causes LED to turn on. 
<P>Normally open push-button causes +5V (logic 1) to appear on input BUSY 
(STATUS PORT - Bit 7). When depressed, push-button closes and ground (logic 0) 
is applied to input Busy. 
<P>Note external source of 5V. 
<P><B>Program Description:</B> When idle, push-button is open and LED is off. On 
depressing push-button, LED blinks on and off at nominally 5 pulses per second. 
<HR>

<P>
<CENTER>
<H3>E. Test Circuitry</H3></CENTER>
<P>Refer to the figure titled Figure #4 - Printer Port Test Circuitry. This 
illustrates a very simple test fixture to allow you to figure out what 
inversions are taking place in the hardware associated with the printer port. 
Program test_prt.c sequentially turns each of the 12 LED's on and then off and 
then continually loops to display the settings on the five input switches. 
<HR>

<CENTER><IMG 
src="Use of a PC Printer Port for Control and Data Acquisition.files/PHAFIG4.gif"> 

<P><B>Fig 4. Printer Port Test Circuitry</B></CENTER>
<HR>

<P><PRE>   
	/* File TEST_PRT.C   
	**   
	** Program to exercise 12 outputs and five inputs.   
	**   
	** Program sequentially turns off LEDs on Bits 7, 6, 5, ... 0 on the   
	** Data Port, and then Bits #, 2, 1 and 0 on the Control Port.  Each   
	** LED is held off for nominally 1 second.  Note that an LED is turned   
	** off with a logic one.  This process is executed once.   
	**   
	** Program then loops, scanning the highest five bits on the Status Port   
	** and continuously displays the content in hexadecimal.   
	**   
	** P.H. Anderson, Dec 25, '95   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -