A TWO-CHIP I/O EXPANDER FOR IBM PC PARALLEL PRINTER PORT
Francis J. Deck
fdeck@grumpy.helios.nd.edu
INTRODUCTION
A two-chip circuit which connects to the parallel printer
port of an IBM PC or compatible computer provides 16
TTL-compatible i/o lines which are programmable in 4 groups
of 4 bits. A short program in Turbo Pascal is given as an
example of how to program the interface. The circuit can be
expanded at the cost of one additional chip per 16 i/o bits.
Total cost for the circuit is well under $10, using
mail-order components.
CIRCUIT DESCRIPTION
Refer to the schematic diagram. Four Data lines from the
parallel printer port are fed through a 74LS126 tri-state
buffer. The outputs of the '126 are fed back into four
Status inputs on the printer port. The Output Enable (OE)
lines of the '126 are controlled by the PC, and the result
is a 4-bit bidirectional "bus" which is shown as a double
vertical bar.
The 8243 is a specialized circuit which is part of the 8048
microcontroller family, and is intended for expanding the
i/o ports of the 8048/49. It connects to the 4-bit bus, and
has 4 4-bit i/o ports. It is controlled by a Chip Select
(CS') line and a Program (PROG) line.
To execute an 8243 operation, the PC places a 4-bit
"instruction" on the bus, with the PROG line HIGH, and then
pulls the PROG line LOW. If a "write" instruction is
requested, the data to be written is placed on the bus, and
the PROG line returned to a HIGH state. If a "read"
instruction is requested, the 8243 places the input data on
the bus. The driver software anticipates this, and disables
the outputs of the '126, so that data can flow from the 8243
back into the PC via the Status inputs.
None of this happens if the CS' line is HIGH, so multiple
8243s can share the same 4-bit bus, as long as the PC can
control the CS' line of each 8243 separately. Although not
shown in the schematic or implemented in the software
listing, an additional 16 i/o bits can be implemented by
adding a second 8243, whose CS' line is controlled by D7
(pin 9) from the PC.
Note that the four ports are identified as P4 through P7, so
that, e.g. P41 corresponds to bit 1 of port P4.
SCHEMATIC DIAGRAM
IBM PC Parallel
Printer Port:
8 6 --------- 2
D6 >------------------------------|CS' P40|-------o P40
7 7| |3
D5 >------------------------------|PROG P41|-------o P41
2 2 -------- 3 11| |4
D0 >--------|1A 1Q|-----||-----|P20 P42|-------o P42
3 5| |6 || 10| |5
D1 >--------|2A 2Q|-----||-----|P21 P43|-------o P43
4 9| |8 || 9| |1
D2 >--------|3A 3Q|-----||-----|P22 P50|-------o P50
5 12| |11 || 8| |23
D3 >--------|4A 4Q|-----||-----|P23 P51|-------o P51
6 1| | || | |22
D4 >--------|1OE | || | P52|-------o P52
| 4| IC1 | || | IC2 |21
|----|2OE | || | P53|-------o P53
| 10| | || | |20
|----|3OE | || | P60|-------o P60
| 13| | || | |19
----|4OE | || | P61|-------o P61
13 -------- || | |18
S4 <-----------------------|| | P62|-------o P62
12 || | |17
S5 <-----------------------|| | P63|-------o P63
10 || | |13
S6 <-----------------------|| | P70|-------o P70
11 || | |14
S7 <-----------------------|| | P71|-------o P71
18 | |15
GND >------Gnd | P72|-------o P72
| |16
| P73|-------o P73
---------
INTEGRATED CIRCUITS AND POWER CONNECTIONS
# Type +5 Gnd
-- ---- --- ---
IC1 74LS126 14 7
IC2 8243 24 12
PARTS LIST
The prices shown here are taken from Catalog #20 (1992) of:
JDR Microdevices
2233 Samaritan Drive
San Jose, CA 95124
800-538-5000
Description Cat. # Price
----------- ------ -----
8243 IC 8243 2.95
74LS126 IC 74LS126 .39
24-pin IC socket 24 PIN ST .20
14-pin IC socket 14 PIN St .11
DB25 male plug DB25P .69
-----
TOTAL: 4.34
SOFTWARE LISTING
{-------- 8243 i/o expander controller --------}
program e8243;
const
cs = 64; {8243 chip select}
prog = 32; {8243 program line}
oe = 16; {74LS126 output enable}
p4 = 0; {identifier corresponding to hardware port P4}
p5 = 1; {and so on}
p6 = 2;
p7 = 3;
var
ina, outa: word; {input, output port addresses}
{-------- Write an output port ---------}
procedure write_8243 (p: integer; b: byte);
var
instr: byte; {8243 instruction}
begin
instr := p + 4; {signifies "write to port ch"}
port [outa] := instr + prog + oe;
port [outa] := instr + oe;
port [outa] := (b and 15) + oe;
port [outa] := (b and 15) + prog + oe;
port [outa] := prog + cs + oe;
end;
{-------- Read an input port -------}
function read_8243 (p: integer): byte;
var
instr: byte; {8243 instruction}
begin
instr := p; {signifies "read from port ch"}
port [outa] := instr + prog + oe;
port [outa] := instr + oe;
port [outa] := 0;
read_8243 := (port[ina] div 16) xor 8;
port [outa] := prog + cs;
end;
{-------- Mainline --------}
const
nlpt = 1;
base: word = $40;
offs: array[1..3] of word = ($08,$0A,$0C);
begin
outa := memw[base:offs[nlpt]];
ina := outa + 1;
port [outa] := cs + prog;
write_8243 (p4,15); {set port P4 to all 1's}
writeln (read_8243(p5)); {read port P5}
end.