This article describes the structure of parallel ports and the reading and writing of parallel ports and how to obtain the port status.
Classification of parallel interfaces: spp (standard parallel interface), EPP (enhanced parallel interface), and ECP (Extended Parallel Port)
The standard parallel port (SPP) is also the earliest port definition. Its main functions are as follows: 1. The parallel port provides eight data lines for parallel bytes transmission. 2: the computer can send a selection signal to the printer through the data cable to notify the printer that it is ready to receive data. 3: The printer sends a response signal (NACK) to the computer after receiving the data ). The meanings of signal lines are described in the table below.
The emergence of the enhanced parallel port (EPP) provides a higher-performance connection mode, and the East China Road is backward compatible with all existing parallel interfaces and peripherals. Unlike spp, the original 17 signals are redefined. In these 17 signals, EPP uses 14 of them for transmission, handshaking, and intercommunication, the remaining three signals can be defined by the peripheral designer.
The general structure of parallel interfaces:
The parallel port generally has 25 pins, including 8-bit data lines, 5-bit printer status lines, and 4-bit control lines. These pins are described in detail below:
(Note: 1:> output, indicating that the computer sends to the printer; input, indicating that the printer sends to the computer,
2:> low-level valid signals are marked with dashes or asterisks (for example, S7 *). High-level valid signals are not marked with dashes or asterisks)
Pin No. |
Name |
Data bit |
Register |
Data direction |
Definition |
1 |
/Strobe |
C0 * |
|
Output |
Select the communication number. The low-level valid signal indicates that online data has arrived. |
2 |
D0 |
DATA_1-DATA_8 |
D1-D8 |
Output |
The eight-digit data line can only output data under the SPP command. |
3 |
D1 |
Output |
4 |
D2 |
Output |
5 |
D3 |
Output |
6 |
D4 |
Output |
7 |
D5 |
Output |
8 |
D6 |
Output |
9 |
D7 |
Output |
|
10 |
/Ack |
S6 |
Status |
Inbound |
The last character has been recruited. |
11 |
Busy |
S7 * |
Status |
Inbound |
Indicates that the printer is busy and cannot receive data again. |
12 |
PE |
S5 |
Status |
Inbound |
No printer paper. |
13 |
Select |
S4 |
Status |
Inbound |
Select input to insert a high level, indicating that the printer is on standby. |
14 |
Auto feed |
C1 * |
Control |
Output |
Automatic Feed, low-level valid signal, notifies the printer to automatically wrap each carriage return. |
15 |
/Error |
S3 |
Status |
Inbound |
Error. The signal is sent from the printer to the computer, indicating that the printer is in an error state. |
16 |
/Init |
C2 |
Control |
Output |
Initialize a low-level valid signal, which is used to reset the printer. |
17 |
/Selin |
C3 * |
Control |
Output |
Select input. The low-level valid signal indicates the selected printer. |
18 |
Gnd |
|
|
--- |
Signal grounding |
19 |
Gnd |
|
|
--- |
Signal grounding |
20 |
Gnd |
|
|
--- |
Signal grounding |
21 |
Gnd |
|
|
--- |
Signal grounding |
22 |
Gnd |
|
|
--- |
Signal grounding |
23 |
Gnd |
|
|
--- |
Signal grounding |
24 |
Gnd |
|
|
--- |
Signal grounding |
25 |
Gnd |
|
|
--- |
Signal grounding |
Common printer ports: For LPT1: 0x378, the data sending Address, 0x379 is the printer status address, and 0x37a is the computer control address to the printer, to make the program generic, we can obtain this address from the Registry. For Windows CE, this value is stored in {HKEY_LOCAL_MACHINE // drivers // builtin // parallel // iobase }. then we can control the three ports to achieve simple parallel programming.
The following is a detailed explanation of the printer status port and printer control port:
Control Port:
0x37a |
1 |
1 |
Input control |
Interrupted |
Line 17 |
16-Wire |
Line 14 |
Line 1 |
This 0x37a computer controls the printer address, which can generate the necessary signal for printer control. It can be written, and the two-height (7 and 8) is useless, 6th-bit write 1 indicates that data can be output to the parallel port. The fifth interrupt signal (IRQ en). With the help of the Status port signal (NACK), the driver can use this signal to control the generation or failure of the interrupt signal. The 3, 2, and 1 0 digits respectively control the 17th, 16th, 14th, and 1st lines. (You can control their statuses.) For more information, see the previous table.
Status Port:
Zero x 379 |
(S7) 11 busy |
(S6) 10 response |
(S5) 12 paper shortage |
(S4) 13 online |
(S3) 15 Error |
S2 |
S1 |
S0 |
0x379 is the printer status address, which is readable. You can easily read the printer status through a port printer adapter.
Signal marked as S7 indicates the highest bit, so indicates the lowest Bit, only five signals of the S3-S7 is really useful signal. Their specific signal functions are described as follows:
S7 * (busy): The printer uses this signal to indicate that the printer is busy and cannot receive data. It should be emphasized that the signal is reversed when it passes through the adapter board, so the low level on the connector becomes high when it reaches the microprocessor.
S6 (NACK): When the adapter sends the selected communication number, the printer generates this signal as a response. Generally, the signal is a high level. After the printer is selected, the printer first sets the signal to a low level and then returns the high level.
S5 (PE): When the printer lacks paper, it generates such a signal. Generally, the signal is kept low from the printer. After the printer is used up, the signal will change to a high level.
S4 (select): When the printer returns to normal operation, it inserts a high-level signal. When the printer is in an invalid state, the access signal changes to a low level.
S3 (nerror): This mail error signal is generated when a printer error occurs. There are many causes of errors, such as printing paper blocking or internal errors. When an error occurs, the signal is set to a low level.
The following are the values of the (Al) Status Registers corresponding to the printer in Windows CE:
1:> when the printer is not connected, the register Al value is 127, and the corresponding binary value is: 1111111
2:> when the printer is not lit with paper lights, the register Al value is 144, and the corresponding binary value is: 10010000.
3:> when the printer is lit with a paper lamp, the register Al value is 119, and the corresponding binary value is 11101111.
4:> the Al value of the printer registers 223 without paper shortage. The binary value is 11011111.
5:> when the printer is not started, the ah value is 207, and the binary value is 11001111.
The following describes the parallel programming control:
(Programming Control example) (for assembly code)
// This code is a parallel port that writes data to the printer and sends control information.
# Define lpt_clear_mask 0x40
# Define lpt_strobe_hi 0x0d
# Define lpt_strobe_lo 0x0c
# Define lpt_status_bits 0xf8
# Define lpt_bits_invert 0x48
# Define lpt_notbusy 0x80
# Define lpt_paperout 0x20
# Define lpt_select 0x10
# Define lpt_nfault 0x08
# Define lpt_timeout 0x01
Void outbyte (ulong dataport, byte databyte ){
# If x86
_ ASM {
MoV dx, word PTR [dataport]
MoV Al, byte PTR [databyte]
Out dx, Al
Out dx, Al
Add dx, 2
In Al, DX
And Al, lpt_clear_mask
MoV Cl, Al
Or Al, lpt_strobe_hi
Out dx, Al
Out dx, Al
Out dx, Al
Out dx, Al
Or Cl, lpt_strobe_lo
MoV Al, Cl
Out dx, Al
}
# Else
Write_port_uchar (puchar) dataport, databyte );
Dataport + = 2;
Databyte = (read_port_uchar (puchar) dataport) & lpt_clear_mask)
| Lpt_strobe_hi;
Write_port_uchar (puchar) dataport, databyte );
Databyte = (read_port_uchar (puchar) dataport) & lpt_clear_mask)
| Lpt_strobe_lo;
Write_port_uchar (puchar) dataport, databyte );
# Endif
}
// This code segment reads the current status of the printer.
Byte checkstatus (unsigned port ){
Byte Bret;
# If x86
_ ASM {
MoV dx, word PTR [port]
Checkme:
In Al, DX
MoV ah, Al
NOP
NOP
In Al, DX
CMP Al, ah
Jnz checkme
And ah, lpt_status_bits
XOR ah, lpt_bits_invert
Test ah, lpt_paperout or lpt_nfault
Jnz cs_haserror
Test ah, lpt_select
JZ cs_haserror
And ah, lpt_notbusy
JZ cs_haserror
XOR eax, eax
Cs_haserror:
MoV [Bret], Al
}
# Else
Byte bstatus;
Do {
Bret = bstatus = read_port_uchar (puchar) Port );
} While (bstatus! = Read_port_uchar (puchar) Port ));
Bstatus & = lpt_status_bits;
Bstatus ^ = lpt_bits_invert;
If (! (Bstatus & (lpt_paperout | lpt_nfault ))&&
(Bstatus & lpt_select) & (bstatus & lpt_notbusy ))
Bret = 0;
# Endif
Return Bret;
}
// The End