Parallel port
basics:
In
computers, ports are used mainly for two reasons: Device control and
communication. We can program PC's Parallel ports for both. Parallel
ports are mainly meant for connecting the printer to the PC. But we can
program this port for many more applications beyond that.
Parallel ports are easy to program and faster compared to the serial
ports. But main disadvantage is it needs more number of transmission
lines. Because of this reason parallel ports are not used in long
distance communications. Let us know the basic difference between
working of parallel port and serial port. In serial ports, there will be
two data lines: One transmission and one receive line. To send a data in
serial port, it has to be sent one bit after another with some extra
bits like start bit, stop bit and parity bit to detect errors. But in
parallel port, all the 8 bits of a byte will be sent to the port at a
time and a indication will be sent in another line. There will be some
data lines, some control and some handshaking lines in parallel port. If
three bytes of data 01000101 10011100 10110011 is to be sent to the
port, following figures will explain how they are sent to the serial
and parallel ports respectively. We can understand why parallel port
communication is faster compared to that of serial.
Parallel port
basics:
In
computers, ports are used mainly for two reasons: Device control and
communication. We can program PC's Parallel ports for both. Parallel
ports are mainly meant for connecting the printer to the PC. But we can
program this port for many more applications beyond that.
Parallel
ports are easy to program and faster compared to the serial ports. But
main disadvantage is it needs more number of transmission lines. Because
of this reason parallel ports are not used in long distance
communications. Let us know the basic difference between working of
parallel port and serial port. In serial ports, there will be two data
lines: One transmission and one receive line. To send a data in serial
port, it has to be sent one bit after another with some extra bits like
start bit, stop bit and parity bit to detect errors. But in parallel
port, all the 8 bits of a byte will be sent to the port at a time and a
indication will be sent in another line. There will be some data lines,
some control and some handshaking lines in parallel port. If three bytes
of data 01000101 10011100 10110011 is to be sent to the port, following
figures will explain how they are sent to the serial and parallel ports
respectively. We can understand why parallel port communication is
faster compared to that of serial.
Serial port: Data
transmission will be bitwise, one after another.
figure 1.0
�
electroSofts.com
|
For more detail on RS232 serial port programming and connections,
read our article "Serial
Communication using RS232 port". This article
explains serial port programming with example source code PC to PC
chat in DOS with direct cable connection.
electroSofts.com
will soon bring you an article on serial port programming in
Windows. |
Parallel
Port: Data transmission is byte wise:
Whole byte at a time.
figure 1.1
�
electroSofts.com |
In the PC there will be
D-25 type of female connector having 25 pins and in the printer, there
will be a 36-pin Centronics connector.
Connecting cable will combine these connecter using following
convention. Pin structure of D-25 and Centronics connecters are
explained bellow.
figure 1.2 |
D25- Pin Number |
Centronics 36 Pin Number |
Function |
1 |
1 |
Strobe |
2
to 9 |
2 to 9 |
Data Lines |
10 |
10 |
Acknowledgement |
11 |
11 |
Busy |
12 |
12 |
Out of Paper |
13 |
13 |
Select |
14 |
14 |
Auto feed |
15 |
15, 32 |
Error |
16 |
16, 31 |
Init |
17 |
17, 36 |
Select In |
18 to 25 |
18
to 30, 33 |
GND |
- |
34, 35 |
N/C |
Table 1.0: Pin numbers
and functions
Now
let us know how communication between PC and printer takes place.
Computer places the data in the data pins, then it makes the strobe low.
When strobe goes low, printer understands that there is a valid data in
data pins. Other pins are used to send controls to the printer and get
status of the printer, you can understand them by the names assigned to
the pins.
To use
the printer port for applications other than printing, We need to know
how ports are organized. There are three registers associated with LPT
port: Data register, Control register and Status register. Data register
will hold the data of the data pins of the port. That means, if we store
a byte of data to the data register, that data will be sent to the data
pins of the port. Similarly control and status registers. The following
table explains how these registers are associated with ports.
Pin No (D-Type 25)
|
SPP Signal
|
Direction In/out
|
Register.bit
|
1*
|
nStrobe
|
In/Out
|
Control.0
|
2
|
Data 0
|
In/Out
|
Data.0
|
3
|
Data 1
|
In/Out
|
Data.1
|
4
|
Data 2
|
In/Out
|
Data.2
|
5
|
Data 3
|
In/Out
|
Data.3
|
6
|
Data 4
|
In/Out
|
Data.4
|
7
|
Data 5
|
In/Out
|
Data.5
|
8
|
Data 6
|
In/Out
|
Data.6
|
9
|
Data 7
|
In/Out
|
Data.7
|
10
|
nAck
|
In
|
Status.6
|
11*
|
Busy
|
In
|
Status.7
|
12
|
Paper-Out / Paper-End
|
In
|
Status.5
|
13
|
Select
|
In
|
Status.4
|
14*
|
nAuto-Linefeed
|
In/Out
|
Control.1
|
15
|
nError / nFault
|
In
|
Status.3
|
16
|
nInitialize
|
In/Out
|
Control.2
|
17*
|
nSelect-Printer/ nSelect-In
|
In/Out
|
Control.3
|
18 - 25
|
Ground
|
Gnd
|
|
Table 1.1: Pin directions and associated registers.
* Pins
with * symbol in this table are hardware inverted. Than means, If a pin
has a 'low' ie. 0V, Corresponding bit in the register will have value 1.
Signals
with prefix 'n' are active low. That means, Normally these pins will
have low value. When it needs to send some indication, it will become
high. For example, Normally nStrobe will be high, when the data is
placed in the port, computer makes that pin low.
Normally, data, control and status registers will have following
addresses. We need these addresses in programming later.
Register |
LPT1 |
LPT2 |
Data register (Base Address + 0) |
0x378 |
0x278 |
Status register (Base Address + 1) |
0x379 |
0x279 |
Control register (Base Address + 2) |
0x37a |
0x27a |
Note:
All the parallel ports do not have bidirectional capability. Earlier
parallel ports had only output enabled in data pins since printers only
inputs data. But latter, to make parallel port capable of communicating
with other devises, bidirectional ports are introduced.
By
default, data port is output port. To enable the bidirectional property
of the port, we need to set the bit 5 of control register.
To know the details of
parallel ports available in your computer, follow this procedure:
-
Right click on My
Computer, go to "Properties".
-
Select the tab
Hardware, Click Device manager.
-
You will get a tree
structure of devices; In that Expand "Ports(Com1 & LPT)".
-
Double Click on the
ECP Printer Port(LPT1) or any other LPT port if available.
-
You will get details
of LPT port. Make sure that "Use this Port (enable)" is selected.
-
Select tab recourses.
In that you will get the address range of port.
To
start programming, you will need a D-25 type Male connector. Its pin
structures can be found in the connector as follows:
Programming the printer port in DOS:
To
start programming the port, we will use DOS. In DOS we have commands to
access the port directly. But, these programs will not work on
the systems based on Windows XP, Windows NT or higher versions. For
security reason, higher versions of the windows does not allow accessing
the port directly. To program the parallel port in these systems, we
need to write kernel mode driver. In the part II, I am going to explain
about programming the parallel port in windows XP. If you want to run
the same program in Windows XP, For studying you can use the
technique that
I have posted in this forum.
When we
want to find out whether particular pin of the port is high or low, we
need to input the value of corresponding register as a byte. In that, we
have to find out whether the corresponding bit is high or low using
bitwise operators. We can't access the pins individually. So, you
need to know basic bitwise operations.
Main
bitwise operators that we need are bitwise AND '&' and bitwise OR '|'.
To make a particular bit in a byte high without affecting other bits,
write a byte with corresponding bit 1 and all other bits 0; OR it with
original byte. Similarly, to make particular bit low, write a byte with
corresponding bit 0 and all other bits 1; AND it with original byte.
In
Turbo C, there are following functions used for accessing the port:
-
outportb( PORTID, data);
-
data
= inportb( PORTID);
-
outport( PORTID, data);
-
data
= inport( PORTID);
outport()
function sends a word to port, inport() reads a word from the port.
outportb() sends a byte to port and inportb() reads a byte from the
port. If you include DOS.H header, these functions will be considured as
macro, otherwise as functions. Function inport() will return a word
having lower byte as data at PORTID and higher byte as data at PORTID+2.
So, we can use this function to read status and control registers
together. inportb() function returns byte at PORTID. outport() writes
the lower byte to PORTID and higher byte to PORTID+1. So this can be
used to write data and control together. outportb() function write the
data to PORTID. outport() and outportb() returns nothing.
Let us
start with inputting first. Here is an example program, copy it and run
in Turbo C or Borland C without anything connected to parallel port.
Then you should see data available in status register and pin numbers
10, 11, 12, 13 and 15 of the parallel port. Pin 11 (active low) is 0 and
all other pins are 1 means it is OK.
/* file: ex1.c
by HarshaPerla for electroSofts.com.
Displays contents of status register of parallel port.
Tested with TurboC 3.0 and Borland C 3.1 for DOS.
*/
#include"stdio.h"
#include"conio.h"
#include"dos.h"
#define PORT 0x378
void main()
{
int data;
clrscr();
while(!kbhit())
{
data=inportb(PORT+1);
gotoxy(3,10);
printf("Data available in status register: %3d (decimal),
%3X (hex)\n", data, data);
printf("\n Pin 15: %d",(data & 0x08)/0x08);
printf("\n Pin 13: %d",(data & 0x10)/0x10);
printf("\n Pin 12: %d",(data & 0x20)/0x20);
printf("\n Pin 11: %d",(data & 0x80)/0x80);
printf("\n Pin 10: %d",(data & 0x40)/0x40);
delay(10);
}
} |
To
understand bitwise operations: you want to find data in pin 15, value of
(data & 0x08) will be 0x08 if bit 3 of register is high, 0therwise.
bit no. 7654 3210
data : XXXX 1XXX
& with : 0000 1000 (0x08 )
-> 0000 1000 (0x08 -> bit 3 is high ) |
bit no. 7654 3210
data : XXXX 0XXX
& with : 0000 1000 (0x08 )
-> 0000 0000 (0x00 -> bit 3 is low) |
We will
use the same logic throughout the article.
Now,
take a D-25 male with cables connected to each pins. Short all the pins
from 18 to 25, call it as ground. Now you can run above program and see
the change by shorting pins 10, 11, 12, 13 and 15 to ground. I prefer
using switches between each input pins and ground. Be careful, do not
try to ground the output pins.
To find
out the availability of ports in a computer programmatically, we will
use the memory location where the address of port is stored.
0x408 |
0x409 |
0x40a |
0x40b |
0x40c |
0x40d |
LPT1 low
byte |
LPT1 high
byte |
LPT2 low
byte |
LPT2 high
byte |
LPT3 low
byte |
LPT3
high
byte |
If you
run the the following code in Turbo C or Borland C, You will get the
addresses of available ports.
/*PortAdd.c
To find availability and addresses of the lpt ports in the
computer.
*/
#include <stdio.h>
#include <dos.h>
void main()
{
unsigned int far *ptraddr; /* Pointer to location of Port
Addresses */
unsigned int address; /* Address of Port */
int a;
ptraddr=(unsigned int far *)0x00000408;
clrscr();
for (a = 0; a < 3; a++)
{
address = *ptraddr;
if (address == 0)
printf("No port found for LPT%d \n",a+1);
else
printf("Address assigned to LPT%d is 0x%X
\n",a+1,address);
ptraddr++;
}
getch();
} |
Next we
will go to check output pins. To check the output, we will use LED's. I
have driven LED's directly from the port. But it is preferred to connect
a buffer to prevent excessive draw of current from the port. Connect an
LED in series with a resister of 1KW or 2.2KW between any of the data pins(2 to 9) and ground. With that, if you run the program given below, you
should see the LED blinking with app. 1 sec frequency.
#include"conio.h"
#include"dos.h"
#define PORT 0x378
void main()
{
while(!kbhit())
{
outportb(PORT, ~inportb(PORT) );
delay(1000);
}
} |
I will
stop this part here itself. Next part of this article is now
ready. In the PART 2, you will learn programming the parallel port in
VC++. PART 2 is designed for the beginners of VC++.
Click here to Read part 2.
Part 3
is having the example using LCD module. There we are going to learn
connecting LCD module to parallel port. Read part
3.
Also Read...
-Programming the Parallel
Port(PART 2): with VC++
-Programming the 16x2 LCD module with Parallel Port:
Example 1
-PC Based Game show/Quiz buzzer: Interfacing project
example 2
-Serial communication via RS232 with C
-Links to port programming related
articles in other sites |