ISSLg - Cours d'électronique
Les ports LPT
Navigation> electronique/automatisme/PC/Ports/LPT

Le port LPT permet le pilotage d'anciennes imprimantes via un bus parallèle. C'est de loin le port le plus simple à piloter pour transformer directement un PC en automate, sans devoir passer par un µC dans l'interface de votre automate. De plus ce port est assez rapide, et en tout cas largement assez rapide que pour piloter un bus I2C !

NB : Actuellement les imprimantes sont pilotées via un port USB, les ports LPT ne sont généralement plus présents sur les cartes mères des nouveaux ordinateurs, soit vous récupérez un ancien PC équipé de ce type de port, soit vous équipez votre PC d'une carte PCI avec un port LPT.


Le brochage et les signaux
Le port LPT se reconnaît à l'arrière du PC par son connecteur BD25 femelle.
En voici la numérotation des broches :

AJOUTER PHOTO

Ces broches correspondent aux signaux suivants :
N° de broches Nom du signal Direction du signal Rôle du signal
1 STROBE PC => Imprimante 0 = données (D0-7) valides : indique à l'imprimante qu'elle peut les lire
2 D0 PC => Imprimante Donnée Bit 0 (LSB)
3 D1 PC => Imprimante Donnée Bit 1
4 D2 PC => Imprimante Donnée Bit 2
5 D3 PC => Imprimante Donnée Bit 3
6 D4 PC => Imprimante Donnée Bit 4
7 D5 PC => Imprimante Donnée Bit 5
8 D6 PC => Imprimante Donnée Bit 6
9 D7 PC => Imprimante Donnée Bit 7 (MSB)
10 ACK PC <= Imprimante 0 = la donnée a été correctement traitée : le PC peut envoyer la donnée suivante
11 BUSY PC <= Imprimante 1 = imprimante occupée (impression d'un caractère ou retour à la ligne en cours, erreur...) : indique au PC d'attendre avant d'envoyer les données suivantes
12 PE PC <= Imprimante 1 = plus de papier
13 SLCT PC <= Imprimante 1 = imprimante connectee
14 AUTO FEED XT PC => Imprimante 0 = retour automatique de la tête d'impression en début de ligne après chaque impression de ligne
15 ERROR PC <= Imprimante 0 = erreur d'impression
16 INIT PC => Imprimante 0 (50µs min) = reset de l'imprimante
17 SLCT IN PC => Imprimante 0 = sélectionne l'imprimante
18-25 GND 0V de référence NB : chaque fil de masse est torsardé avec un fil de donnée (D0-7) pour le blinder contre les parasites

Ce sont des signaux TTL :
0 logique1 logique
Entrées
(PC <= Imprimante)
0,0V à 0,8V2,0V à 5,0V
Sorties
(PC => Imprimante)
0,0V à 0,4V2,5V à 5,0V


Protocole d'envoi par le PC de caractères à imprimer :
Etapes Données
D0-7
STROBE BUSY ACK
Etat de repos Sans importance 1 0 1
Le PC place un caractère à imprimer sur le bus de donnée Caractère à imprimer 1 0 1
Le PC indique à l'imprimante qu'un caractère est placé sur le bus de donnée en mettant STROBE => 0 Caractère à imprimer 0 0 1
L'imprimante indique au PC qu'elle a bien lu le caratère et quelle est occupée à le traiter en mettant BUSY => 1 Caractère à imprimer 0 1 1
Le PC relache le STROBE => 1 Caractère à imprimer 1 1 1
L'imprimante indique au PC la fin du traitement du caractère en relachant BUSY => 0Sans importance101
L'imprimante indique au PC que le caractère a été correctement traité en envoyant une impulsion (de 2 à 5 µs) sur la ligne ACK :
Début de l'impulsion 
Sans importance100
Fin de l'impulsion
Le PC peut envoyer le caractère suivant...
Sans importance101
VERIFIER SI C'EST BIEN LE BUSY QUI FAIT REPASSER LE STROBE A 1 ???



L'adressage
Le contrôle des signaux d'un port LPT se fait :
L'adresse de base du port (BA) représente l'adresse du registre DATA_LATCH
L'adresse suivante (BA+1) représente l'adresse du registre PRINTER_STATUS
L'adresse suivant la suivante (BA+2) représente l'adresse du registre PRINTER_CONTROLS

Le PC peut avoir plusieurs ports LPT, voici les adresses typiques (en hexadecimal) des 3 premiers ports LPT :
PortsAdresse de base
(BA)
Adresse de DATA_LATCH
(BA)
Adresse de PRINTER_STATUS
(BA+1)
Adresse de PRINTER_CONTROLS
(BA+2)
LPT10x3780x3780x3790x37A
LPT20x2780x2780x2790x27A
LPT30x3BC0x3BC0x3BD0x3BE
Si vous avez des doutes sur l'adresse de base de votre port LPT, vous pouvez aller la lire au démarrage de votre PC dans le BIOS, ou encore dans le gestionnaire de périphériques de Windows.
NB : Il est même possible de rendre les registres bi-directionnels via le BIOS, mais nous n'utiliserons pas ici cette fonctionnalité pour des raisons de portabilités des applications (nécessité d'aller reconfigurer le BIOS dès que l'on change de PC).

Voici la correspondance des bits de ces registres avec les signaux du port LPT :

DATA_LATCH
BitsN° Broches BD25Nom du signalÉtat de repos
(au niveau du BD25)
7 (MSB)9D70
68D60
57D50
46D40
35D30
24D20
13D10
0 (LSB)2D00


PRINTER_STATUS
BitsN° Broches BD25InverseurNom du signalÉtat de repos
(au niveau du BD25)
7 (MSB)11INV*BUSY1
610ACK0
512PE0
413SLCT0
315ERROR0
2NC*
1NC*
0 (LSB)NC*
Attention, certains bits passent par un inverseur (INV*), tous les bits de sont pas connectés (NC*).


PRINTER_CONTROLS
BitsN° Broches BD25InverseurNom du signalÉtat de repos
(au niveau du BD25)
7 (MSB)NC*
6NC*
5NC*
4NC*IRQ0
317INV*SLCT IN1
216INIT0
114INV*AUTO FD XT1
0 (LSB)1INV*STROBE1
Attention, certains bits passent par un inverseur (INV*), tous les bits de sont pas connectés (NC*).
Lorsque le bit 4 (IRQ) est à 1, l'envoi d'un ACK (FLANC MONTANT OU DESCENDANT ???) par l'imprimante génère une demande d'interruption dans le PC.



La programmation
Une première possibilité est que l'automate simule le protocole d'une imprimante en gérant les signaux STROBE, BUSY et ACK.
La programmation se fait alors simplement par l'envoi d'octets sur le périphérique système LPT. Le gros désavantage de cette technique est que votre PC ne sait qu'uniquement envoyer des données à l'automate, et n'a aucune possibilité d'en lire en retour. Votre automate est un simple périphérique de sortie... tout comme une imprimante.

Pour que l'automate soit un systeme entrées/sorties, il faut directement programmer les registres du port LPT. Nous disposons alors de 12 bits en écritures (registres DATA_LATCH=8bits + PRINTER_CONTROLS=4bits) et de 5 bits en lectures (registre PRINTER_STATUS=5bits). Ce qui est largement suffisant, avec quelques astuces, pour piloter un automate. C'est ce que nous allons faire ci-dessous.


Sous Windows 98
Les versions de Windows 3.X et 9X sont basées sur un noyau DOS. Ce noyau permet la programmation directe des registres du port LPT.

Avec Delphi

Lecture du registre qui est à l'adresse "IOport" (la fonction retoune le byte de ce registre) :
FUNCTION PortIn(IOport: WORD): BYTE; ASSEMBLER; REGISTER;
ASM
  MOV DX,AX
  IN AL,DX
END;
 
Ecriture dans le registre qui est à l'adresse "IOport" du byte "Value" :
PROCEDURE PortOut(IOport: WORD; Value: BYTE); ASSEMBLER; REGISTER;
ASM
  XCHG DX,AX
  OUT DX,AL
END;


Téléchargement d'un programme de commande d'un port LPT (lecture/écriture des registres/broches + test de vitesse + fct sniffer ?)
Code du programme.


Sous Linux/Ubuntu
Le noyau Linux bloque par défaut l'écriture directe sur les registres du port LPT.

Avec Lazarus, vous devez utiliser la librairie 'x86' :
Reference for unit 'x86': Procedures and functions
fpIOperm    Set permission on IO ports
ReadPortB   Read bytes from a PC port
WritePortB  Write byte to PC port
Voir : http://lazarus-ccr.sourceforge.net/docs/rtl/x86/index-5.html

Le programme doit lever cette interdiction via la fonction ...
fpIOperm    Set permission on IO ports
Notez qu'ensuite il faut lancer le programme depuis un terminal en mode super-utilisateur (sudo monprogramme).

Vous pouvez ensuite accéder aux registres du port LPT via
ReadPortB   Read bytes from a PC port
WritePortB  Write byte to PC port


Sous Windows XP
Depuis Windows 2000, le noyau de ces OS est hérité de Windows NT. Ce noyau interdit l'écriture directe sur les registres du port LPT. Vous devez passer par la DLL  IO.DLL (ou io32.dll ou encore inpout32.dll) pour programmer ces registres. (NB : io.dll à copier C:\windows\systeme32\io.dll)

Avec Delphi

procedure
PortOut(Port : Word; Data : Byte); stdcall; external 'io.dll';
function
PortIn(Port : Word) : Byte;stdcall; external 'io.dll';

A COMPLETER



Le pilotage d'un bus I2C via un port LPT

Interface électronique

Programmation de l'interface



La pilotage de 4 ports de 8 bits via un port LPT

Interface électronique

Programmation de l'interface




Auteur : Philippot Marc - 18/08/2010