|
16 Bits Input/Output Unit |
One thing I like to do with computers is controlling hardware. That's the
reason for creating a parallel communication interface connected to the
printer port of a computer.
This is way before I gathered knowledge about
USB interfaces.
First I started with a Z80PIO chip on a Z80CPU
controlled ZX Spectrum. When I bought my first laptop I knew I would need a
complete new interface.
The Z80PIO interface had 16 channels of witch each
channel could be configured for input or output. Because of the
limitations of the parallel port I decided to create 16 input channels and
16 output channels.
The top of the case has an experiment feature with build-in AD
converter.
|
|
See the drawings below (click on them for enlargements) for detailed info on
used components. Because the parallel port has no 5V supply, you'll need a
separate one.
|
|
If you just need an 8 channel input/output interface, click on the
drawing above for the complete schematic.
I'll recommend the 16 channel version though!
|
If you wonder how the circuit board should look after building it, I use
Euro board for all my prototypes, as you can see below.
To create this you'll need a bit of experience in the TTL systems.
Below is some information about controlling the Parallel port.
Here is a listing for Quick basic which you can reference. It's ready to control
the 16 bit version. Just copy the text and save it in Notepad as PIO16.BAS.
Remember to disconnect any printer or scanner
connected to the parallel port !!
CLS
REM GOTO BIT8
GOTO B16
T = 1
A = 1
B = 16
LOP: V = A
D = 1
GOSUB CONTO
V = B
D = 2
GOSUB CONTO
A = A * 2: IF A = 256 THEN A = 1
B = B * 2: IF B = 256 THEN B = 1
FOR c = 1 TO 1000: NEXT c
GOTO LOP
B16: T = 1
BIT16: FOR A = 0 TO 255: B = 255 - A
REM A = INT(RND * 255) + 1
REM B = INT(RND * 255) + 1
V = A: D = 1
GOSUB CONTO
V = B: D = 2
GOSUB CONTO
REM FOR c = 1 TO 500: NEXT c
D = 3: GOSUB CONTI
v1 = V
D = 4: GOSUB CONTI
v2 = V
va = (INT(v1 / 8)) + ((INT(v2 / 8))
* 16)
IF va <> A THEN PRINT "Ain=";
va; " Auit="; A: T = T + 1
REM FOR c = 1 TO 500: NEXT c
D = 5: GOSUB CONTI
v1 = V
D = 6: GOSUB CONTI
v2 = V
va = (INT(v1 / 8)) + ((INT(v2 / 8))
* 16)
IF va <> B THEN PRINT "Bin=";
va; " Buit="; B: T = T + 1
FOR c = 1 TO 1000: NEXT c
NEXT A
GOTO BIT16
BIT8: FOR A = 0 TO 255
OUT &H378, (A)
OUT &H37A, (1)
OUT &H37A, (2)
v1 = INP(&H379)
OUT &H37A, (4)
v2 = INP(&H379)
OUT &H37A, (0)
va = (INT(v1 / 8)) + ((INT(v2 / 8))
* 16)
IF va <> A THEN PRINT va; "
";
FOR c = 1 TO 500: NEXT c
NEXT A
GOTO BIT8
CONTI: OUT &H37A, (D + 8)
FOR c = T TO 0 STEP -1: NEXT c
OUT &H37A, (D)
FOR c = T TO 0 STEP -1: NEXT c
V = INP(&H379)
FOR c = T TO 0 STEP -1: NEXT c
OUT &H37A, (D + 8)
FOR c = T TO 0 STEP -1: NEXT c
OUT &H37A, (8)
FOR c = T TO 0 STEP -1: NEXT c
RETURN
CONTO: OUT &H378, (V)
FOR c = T TO 0 STEP -1: NEXT c
OUT &H37A, (D + 8)
FOR c = T TO 0 STEP -1: NEXT c
OUT &H37A, (D)
FOR c = T TO 0 STEP -1: NEXT c
OUT &H37A, (D + 8)
FOR c = T TO 0 STEP -1: NEXT c
OUT &H37A, (8)
FOR c = T TO 0 STEP -1: NEXT c
RETURN
Below is the assembler source code to set waitloop variable. The value of
this variable should be high on fast PC's. You need to connect the outputs of
the interface directly to the inputs, so OUT0 to IN0 and so on.
; Scumari R&D 1996
; Parallel 16 bit In/Out interface suppressing test
; IO.ASM
JMP START ;
TWRD: DW 1 ;
START: MOV CX,255 ;
LOP: MOV AL,1 ;
MOV AH,CL ;
CALL COUT ; Value in CL to output 1
MOV AL,2 ;
MOV AH,CH ;
CALL COUT ; Value in CH to output 2
;
MOV AL,3 ;
CALL CIN ;
CMP CL,BL ;
JNZ TELW ;
MOV AL,5 ;
CALL CIN ;
CMP CH,BL ;
JZ NOTEL ;
;
TELW: MOV AX,[TWRD] ;
INC AX ;
MOV [TWRD],AX ;
CMP AX,0 ;
JZ EIND ;
CALL NUMBR ;
NOTEL: DEC CL ;
INC CH ;
;
; MOV BX,65535 ;
;L0: DEC BX ;
; JNZ L0 ;
MOV AH,1 ; Check break keys
INT 16H ;
JZ LOP ;
EIND: MOV AX,[TWRD] ;
CALL NUMBR ;
MOV AH,4CH ;
INT 21H ;
;
; OUT subroutine
; AL=port number AH=Value
;
COUT: MOV DX,0378H ;
PUSH AX ;
MOV AL,AH ;
OUT DX,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
MOV DX,037AH ;
POP AX ;
PUSH AX ;
ADD AL,8 ;
OUT DX,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
;
MOV DX,037AH ;
POP AX ;
PUSH AX ;
OUT DX,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
MOV DX,037AH ;
POP AX ;
PUSH AX ;
ADD AL,8 ;
OUT DX,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
MOV DX,037AH ;
MOV AL,8 ;
OUT DX,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
POP AX ;
RET ;
;
; IN subroutine
; AL=port nummer BL=Value
;
CIN: MOV DX,037AH ;
PUSH AX ;
ADD AL,8 ;
OUT DX,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
MOV DX,037AH ;
POP AX ;
PUSH AX ;
OUT DX,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
MOV DX,0379H ;
IN AL,DX ;
MOV BL,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
MOV DX,037AH ;
POP AX ;
PUSH AX ;
ADD AL,8 ;
OUT DX,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
MOV DX,037AH ;
POP AX ;
INC AL ;
PUSH AX ;
ADD AL,8 ;
OUT DX,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
MOV DX,037AH ;
POP AX ;
PUSH AX ;
OUT DX,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
MOV DX,0379H ;
IN AL,DX ;
MOV BH,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
MOV DX,037AH ;
POP AX ;
PUSH AX ;
ADD AL,8 ;
OUT DX,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
MOV DX,037AH ;
MOV AL,8 ;
OUT DX,AL ;
MOV AX,[TWRD] ;
L0: DEC AX ;
JNZ L0 ;
;
POP AX ;
SHR BL,3 ;
SHL BH,1 ;
AND BH,240 ;
ADD BL,BH ;
RET ;
; SCUMARI R&D
; NUMBERS.BIB
; Number in AX is printed
numbr: PUSH AX ; Print at position 0,0
MOV AH,2 ;
MOV BH,0 ;
MOV DX,0 ;
INT 10H ;
POP AX ;
;
mov cx,10000 ;
call numb ;
mov cx,1000 ;
call numb ;
numbr0: mov cx,100 ;
call numb ;
mov cx,10 ;
call numb ;
mov dl,al ;
add dl,48 ;
jmp near numb2 ;
;
numb: mov dl,48 ;
numb0: sub ax,cx ;
jc numb1 ;
inc dl ;
jmp near numb0 ;
numb1: add ax,cx ;
numb2: push ax ;
mov ah,2 ;
int 21h ;
pop ax ;
ret ;
|