Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1665899
  • 博文数量: 607
  • 博客积分: 10031
  • 博客等级: 上将
  • 技术积分: 6633
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-30 17:41
文章分类

全部博文(607)

文章存档

2011年(2)

2010年(15)

2009年(58)

2008年(172)

2007年(211)

2006年(149)

我的朋友

分类: C/C++

2006-06-23 13:44:00

==============================================================================

Parallel Port Programming

=============================================================================

Parallel port programming is easier than it sounds. The lack of literature on it is surprising, but not a problem. Once you find a few resources of information, you will be set. In this article, I will try to give you the inform ation that you need, without the baffling technicality. Simple does it.

 

 

The Basics:

Access to the parallel port is via a female DB25 on the back of the PC.

 

Pin

Description

Notes

1

/Strobe

PC Output (OC)

2

Data_0

PC Output

3

Data_1

PC Output

4

Data_2

PC Output

5

Data_3

PC Output

6

Data_4

PC Output

7

Data_5

PC Output

8

Data_6

PC Output

9

Data_7

PC Output

10

/ACK

PC Input

11

Busy

PC Input

12

Paper Empty

PC Input

13

Select

PC Input

14

/Autofeed

PC Output

15

/Error

PC Input

16

Init Printer

PC Output

17

/Select_Input

PC Output

18

Ground

 

-25

   

Table 1 - Parallel Port Terminal Designations

 

 

   Every parallel port has three port addresses: Data, Status, and
Control. The three of them are in sequential order. (I.e., if the Data
port is 0x378 then the Control port is 0x378+1, and so on).


So, how do you find out what the port address of your parallel port
it? That depends on your platform. If you are under DOS, you can do
the following:



C:\>debug

-d 0040:08 L8

0040:0008 78 03 78 02 00 00 00 00



The above is an example of an output from the debug command d 0040:08
L8. The port address resides in the memory location 0040:08.



Outputs:



Note that there are eight output on the Data Port, and four additional
outputs on the low nibble of the Control Port (/SELECT_IN, INIT,
/AUTOFEED, and /STROBE).



Luckily, all outputs to the Data Port are true logic. However, the
/SELECT_IN, /AUTOFEED, and /STROBE outputs on the Control Port are
inverted.



Let's see some sample code:


/* codecodecodecodecodecodecodecodecodecodecodecodecodecodecodecodecode */


#include
#include /* needed for ioperm() */
#include /* for outb() and inb() */


#define DATA 0x378
#define STATUS DATA+1
#define CONTROL DATA+2


int main(void)
{
int x = 0x32;
int y = 0x08;


if (ioperm(DATA,3,1)) {
printf("Sorry, you were not able to gain access to the ports\n");
printf("You must be root to run this program\n");
exit(1);
}


outb(DATA, x); /* Sends 0011 0010 to the Data Port */
outb(CONTROL, y^0x0b);

/* SELECT_IN = 1, INIT = 0, /AUTO_FEED = 0, /STROBE = 0 */

return (0);


}

/* codecodecodecodecodecodecodecodecodecodecodecodecodecodecodecodecode */


The above code will work on a Linux. As far as SunOS is concerned there
are two files you need to include (sys/ddi.h) and (sys/sunddi.h) for
the inb() and outb() functions.

You also need to compile with -O or -O2 or similar. The reason for that
is that inb() and family are defined as inline macros, and compiling
them without optimization enabled will cause unresolved references at
link time (Someone in #c came and kept on asking about it, and I thought
I would add this part in). [If people would only read the man pages!].




Inputs:



There are five status leads for the Status Port. (BSY, /ACK, PE,
SELECT, /ERROR). The reasons they are named like that is that it was
originally designed for a printer only. So, we have things like PE
(paper empty), etc.



Beware, the BSY is inverted using hardware, so when receiving input
from there, make sure you invert this bit so you can have what
represents a true logic.





This is how to read the five most significant bits in true logic:



Value = ((inb(STATUS)^0x80) >> 3);



Notice how we inverted the BSY bit using the exclusive-or function.
Then, we shifted the bits 3 times to the right, resulting in the upper
five bits ending up in the lower five bit positions.



0 0 0 BUSY /ACK PE SELECT /ERROR





In conclusion, we should have realized by now that 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 por t and one input on
the status port are inverted by the hardware.



Problems and Solutions:



It may have occurred to you that there are only five bits on the
parallel port for input. This could be a real inconvenience when
interfacing with 8-bit analog to digital converters. One solution to
this problem is to add external circuitry to store the 8-bit result
and gate in 4-bits at a time.



So what can we do about it?



What I did not mention about the Control Port (other than having four
outputs) is that they are bi-directional. They can be outputs and
inputs! Dont you just love how confusing they can get?



Using the control port bi-directional bits is not as simple as just
reading them using inb(). We have to force all the four outputs on the
lower nibble of the control port to logic one. This will result in
external signals being forced on these inputs and then we can read
using the inb().



int i;



outb(CONTROL, 0x0f^0x0b);

/* inverting to go around the hardware inversion */

i = (inb(CONTROL) & 0x0f) ^ 0x0b;





Doing so, we would have solved our little problem there.


Other Handy Macros

Now, let's say you want to send a word to portX and portX+1 instead
of just sending a byte to portX and then another byte to portX+1.
outw(value,portX) will do the trick. inw(portX) will return a word
from portX and portX+1.

Now usually when sending data to the parallel port you need a slight
delay to ensure that the data has been sent, and not lost. Instead of
having extra calls, and more code, there is outb_p() inb_p() outw_p()
and inw_p() which gives us a delay of about 1 microsecond. If that
is not enough delay, you can always #define REALLY_SLOW_IO before
the #include . All Rights Reserved

阅读(778) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~