Un pc c'est bien, on peut observer de jolies couleurs et on se dit que c'est beau tout ça. Il nous sort vite de l'esprit que tout ce qui apparaît n'est que virtuel, les beaux paysages, les lances rockets, la voiture de sport... Ce qui serait bien, s'est de sortir de ce monde virtuel pour faire interagir l'ordinateur avec le monde extérieur, celui qui est réel. Comment est-ce possible ? 


De façon très simple, si vous n'êtes pas trop aventurier, et que vous n'avez jamais osé regarder derrière votre ordinateur pour voir quelle bête féroce s'y cache, il est temps de prendre votre courage à deux mains et d'y faire un petit tour . Dans la multitude de câble, lumière en tout genre et autre ventilateur. On peut observer des connecteurs de différentes tailles dont un sur lequel nous allons un peu nous attarder : le port parallèle. Ce port a été créé il y a quelques dizaines d' années pour y connecter au début les imprimantes, mais très rapidement, on lui ajouta une multitude d'autres périphériques comme les scanners, les lecteurs zip ... A présent ce port est de plus en plus laissé pour compte et remplacé par le port USB nettement plus performant. Il vient même a disparaitre sur de nombreux pc.

Pourquoi s'en servir alors ? Pour une simple raison, il suffit largement pour ce que nous voulons faire, et est très simple à utiliser pour débuter. Pour beaucoup ayant un ordinateur récent, le port parallèle n'existe plus, il sagit d'un connecteur à  broches. Il est possible de trouver sur internet (ebay par exemple) des cartes ajoutant un port parallèle au pc.

Le port lui même

port

brochage

Le port parallèle est composé de 25 broches certaines permettant d'envoyer des informations vers l'extérieur, d'autres permettant d'en recevoir et certaines permettent les deux.

Les broches possèdent un nom, qui actuellement n'est pratiquement plus que quelque chose d'historique de l'époque où il n'y avait que l'imprimante branchée sur ce connecteur. Exemple « PE » signifiait « Paper Error », donc plus de papier dans l'imprimante.

Comme son nom l'indique, le port parallèle envoie et reçoit les informations en parallèle. Cela signifie que si vous écrivez 8 bits sur le port, elles vont apparaîtrent en même temps à l'inverse du port série qui envoie les bits une à une ce qui permet entre autre d'utiliser moins de broches (plus compact).

Ecrire sur le port //

Mais que signifie écrire sur le port parallèle ? Écrire signifie envoyer une information en changeant l'état des broches du port. Quand les broches sont à l'état bas, 0 en binaire, la tension entre la broche et la masse du port est égale à 0. Par contre quand l'état est haut, en binaire 1, la tension entre la broche et la masse est de 5V. Le courant qui peut sortir du port ne dépasse pas 20ma. Pour écrire sur le port, ce n'est pas compliqué vous devez pour cela intégrer quelques lignes de code dans votre programme. Le port parallèle est codé en 8 bit, cela signifie que les valeurs que vous allez envoyer ou recevoir par le port seront comprises entre 0 et 255. Mais il y a 25 broches pas 8 ! Bien sur, le port parallèle est divisé en 3 registres de 8bits, le reste des broches sont les masses.

Chaque registre possède une adresse, pour connaître l'adresse de base de votre port parallèle (celle du registre contrôlant les broches D0 à D7), si vous êtes sous windows : boutton droit sur le poste de travail - propriétés - Matériel - Gestionnaire de périphériques - Port (Com LPT) - Port imprimante - propriétés - ressources. Ouf on y est. On peut y lire Plage d'E/S (entrées/sorties) : paramètre. La première valeur apparaissant (le plus souvent 378) est l'adresse hexadécimale de votre port. Le registre d'adresse 379h est le registre "Etat" et le registre d'adresse 37Ah est Contrôle.

registre

Pour bien comprendre en pratique, réalisons un petit montage, 8 Leds, 8 résistances 1k montées comme tel sur les broches D0 à D7 (registre Données):

led

En fonction de la valeur qui sera écrite sur le port, les différentes leds vont s'allumer où pas. Pour envoyer des informations, il y a plusieurs techniques qui dépendent de la version de Windows que vous utilisez (pour les utilisateurs de linux, si vous êtes parvenu à l'installer, ça ne devrait pas avoir de secret pour vous), en effet sous Windows 95/98/Me on peut accéder directement au port parallèle via l'assembleur ce qui n'est plus possible pour une question de sécurité sous windows NT/2000/XP. Maintenant, il existe une façon propre, facile et gratuite, c'est d'utiliser une DLL déjà programmée et très simple d'utilisation. Cette DLL c'est inpout32.dll, elle permet depuis n'importe quelle version de Windows de communiquer avec le port parallèle sans être inquiété. Pour vous procurer cette DLL, regardez au bas de la page. Pour l'utiliser, il suffit d'appeler la DLL dans votre programme. Regardons un exemple en Delphi, il est bien sur évident que c'est traductible dans n'importe quel langage.

Dans Delphi, après implémentation ajoutez ces deux lignes-ci qui permettent de déclarer les deux fonctions à appeler dans la dll inpout32. N'oubliez pas de copier la dll dans le répertoire de l'exécutable !

function Inp32(port:integer):integer;Stdcall;external 'inpout32.dll' name 'Inp32';
function Out32(port, valeur:integer):integer;Stdcall;external 'inpout32.dll' name 'Out32';

Vous créez ainsi deux fonctions, Inp32 qui permet de lire sur le port, et Out32 qui permet d'écrire. Pour les paramètres, « port » est l'adresse du registre à appeler. Pour rappel, nous avons vu que l'adresse de base port parallèle était habituellement 378h ce qui correspond au registre "données". Ici l'adresse doit être mise sous forme décimale, c'est-à-dire que 378h vaut 888. Si vous voulez vous adresser au registre dont l'adresse est base+1 ou base+2, port vaudra alors : 889 ou 890. Le paramètre « valeur » est la valeur que vous voulez écrire sur le registre, ce nombre sera compris entre 0 et 255 (codé en 8bit). Si vous ne comprenez pas pourquoi 378h vaut 888, utiliser la calculatrice scientifique de Windows, réglez la en hex (hexadécimal) et entrez 378, ensuite cliquez sur Dec (décimal) et vous obtenez la valeur entière qu'il faut envoyer en paramètre.

Bon maintenant, allumons toutes les leds. Si toutes les leds sont à l'état haut, ça signifie que D0 à D7 est à l'état haut, donc qu'en binaire le registre « données » vaut 11111111 et dès lors que l'on doit écrire sur le port là valeur 255 donc il faudra appeler :

Out32 (base, 255) ;


Si maintenant nous ne voulons allumer qu'une led sur deux, le registre vaudra 10101010, soit 170 en décimal, donc nous devons appeler :

Out32 (base, 170) ;


Compris ? bon si vous vous demandez comment on traduit du binaire en décimal, c'est pas compliqué, sortez la calculatrice de Windows, réglez la en mode scientifique, ensuite cliquer sur « Bin », entrez les huits 1 ou 0 puis cliquez sur « Déc », et la valeur apparaît. C'est beau hein !!!

Si maintenant vos leds n'étaient pas placée sur les broches du registre « Données » mais sur celle du registre « Contrôle », alors le paramètre port de la fonction devra valoir base+2. Un programme complet en Delphi montrant comment lire et écrire sur le port parallèle est décrit plus bas...

Introduction aux entrées

Pour conserver cette idée simple, où il suffit de connecter la sortie d'un montage électronique à l'entrée du port parallèle pour pouvoir communiquer, il faut un intermédiaire qui connectera ou non la broche du port parallèle avec la masse suivant la donnée envoyée par le montage (1=tension (ex:5V), 0=tension null (0V)). Une technique pas chère et fiable utilisant un composant classique : le transistor. Ce petit composant créé en 1947 dans les laboratoires BELL, est un interrupteur électronique. Pour rappel, le transistor est constitué de trois couches de silicium de type "P" ou "N". Une couche de type "P" ou "N" est prise en sandwich entre les deux autres couches de type opposé à la première. La couche centrale est appelée "base" et les deux autres "collecteur" et "émetteur". Les transistors se présentent de la manière suivante :

trans

Si on applique une tension entre le collecteur et l'émetteur, il ne circule aucun courant, mais si on vient à faire passer un courant par la base, nous verrons la présence d'un courant sur l'émetteur, celui-ci sera égale au courant de la base multiplié par le coéfficient du transistor Beta ou HFE suivant la notation. Le schéma ci-dessous montre le branchement du transistor comme interface d'entrée :

    • Une entrée du port parallèle au collecteur
    • La sortie du montage, via une résistance pour ne pas endommager la jonction, à la base du transistor
    • La masse à l'émetteur

Nous pouvons maintenant changer facilement l'état de l'entrée du port et la faire passer au niveau 1 ou 0 en fonction de la sortie du montage et sans risquer d'abîmer la carte mère.

schema

Nous remarquons que si la base du transistor passe à l'état haut alors le circuit se ferme et l'entrée « /Ack » (broche 10) du port parallèle est connectée à la masse (état bas) dans le cas contraire, l'entrée reste à l'état haut. Ce mécanisme est possible grâce à la résistance de tirage interne au port parallèle qui maintient un potentiel de 5Volt sur l'entrée quand celle-ci est dans le vide. Un transistor NPN comme le BC547 est très répandu et peu coûteux et est idéal pour ce type d'usage. Pour une sortie de montage en 5V, on peut utiliser une résistance variant entre 470 ohms et 1 kohms. Une résistance plus grande aurait pour conséquence de limiter le courant dans la base du transistor, et donc de ne pas pouvoir faire commuter le transistor. Une autre solution serait d'utiliser des transistors à technologie MOS. Ceux-ci ont la particularité de pouvoir se commander en tension, et non en courant comme les transistors bipolaires. On évite ainsi d'utiliser une résistance.

La lecture depuis un programme (et l'écriture)

Nous allons maintenant voir un petit programme d'exemple pour lire et écrire sur les 3 registres du port parallèle. Commençons le programme, celui-ci pour continuer dans la lancée est écrit en Delphi, mais vu qu'il est fort peu compliqué vous pourrez aisément le traduire dans un autre langage.

Première chose importante, introduisons les deux fonctions Inp32 et Out32 de la Dll inpout32 comme il est indiqué ci-dessus :

implementation
function Inp32(port:integer):integer;Stdcall;external 'inpout32.dll' name 'Inp32';
function Out32(port, valeur:integer):integer;Stdcall;external 'inpout32.dll' name 'Out32';

{$R *.dfm}

Le programme contient énormément de « CheckBox » pour une question de lisibilité, vous pourrez les retrouver directement dans le code source du programme distribué ci-dessous. Pour une prévisualisation voici une image de la form à reproduire :

form

La lecture : Les données qui seront reçues sont des valeurs numériques et comme le port parallèle est codé en 8 bits, ces valeurs numériques varient entre 0 et 255. Pour connaître l'état de chaque entrée séparément nous devrons convertir ces valeurs afin d'obtenir l'état de chaque broches séparement.

Un exemple quand la Bit 7 du registre "Etat" (base + 1 soit 0x379 le plus souvent) «Busy» (broche 11) passe à l'état haut, alors la valeur du registre se voit incrémentée de 2^7 soit 128. Quand «/ACK» (broche 10) passe à l'état haut, l'incrémentation est de 2^6 soit 64. Si les bits 0 à 6 sont à l'état haut et la bit 7 à l'état bas, la valeur du registre sera de 127, ainsi, on sait que si la valeur du registre est strictement supérieur à 127, cela signifie que le bit 7 est à l'état haut. Bon j'en vois qui fronce les sourcilles. Regardons le code.

var recu : cardinal;
var bit : string;
begin

recu := Inp32 (add.value+1);
if recu > 127 then begin

recu := recu-128;
Busy.Checked := true;
end

else Busy.Checked := false;
if recu > 63 then begin

recu := recu-64;
Ack.Checked := true;
end

else Ack.Checked := false;
if recu > 31 then begin

recu := recu-32;
Pe.Checked := true;
end

else Pe.Checked := false;
if recu > 15 then begin

recu := recu-16;
Select.Checked := true;
end

else Select.Checked := false;
if recu > 7 then begin

recu := recu-8;
Error.Checked := true;
end

else Error.Checked := false;


Si recu est supérieur à 127, ça signifie que Busy est à l'état haut, vu que Busy vaut 2^7 soit 128 et que la valeur de recu varie entre 0 et 255. Si Busy est à l'état haut, avant de continuer l'analyse, nous devons retirer 128 de la valeur de recu. Et ainsi de suite pour les 5 broches du registre. Dans le code source du programme, l'entierté du code est mis, c'est-à-dire la lecture du registre « Données » ainsi que « Contrôle ». mais c'est chaque fois la même chose.

Si vous ne comprenez toujours pas comment ça marche, c'est très simple. Prenons une valeur par exemple 72. 72 est inférieur à 127, donc "busy" est à l'état bas, par contre il est supérieur a 63, donc "/ack" est l'état haut. 72-64 = 8 : 8 est supérieur à 7 donc /Error est à l'état haut. Le nombre 72 est formé par l'état haut de "/Ack" et "/Error" ainsi que l'état bas de toutes les autres broches.

Pour l'écriture, c'est très simple on procède de la même façon mais dans l'ordre inverse, on check les cases à écrire (à noter que les cases du registre « Etat » ne peuvent pas être cochée, vu qu'il n'est pas accessible en écriture). Et on clique sur le bouton écrire :

procedure TForm1.EcrireClick(Sender: TObject);
var send : integer;
begin

send := 0;
if (D8.Checked = true) then send := 128;
if (D7.Checked = true) then send := send + 64;
if (D6.Checked = true) then send := send + 32;
if (D5.Checked = true) then send := send + 16;
if (D4.Checked = true) then send := send + 8;
if (D3.Checked = true) then send := send + 4;
if (D2.Checked = true) then send := send + 2;
if (D1.Checked = true) then send := send + 1;
Out32 (add.value, send);
send := 0;
if (Selin.Checked = true) then send := send + 8;
if (Init.Checked = true) then send := send + 4;
if (Autofeed.Checked = true) then send := send + 2;
if (Strobe.Checked = true) then send := send + 1;
Out32 (add.value+2, send);

end;


On remarque la petite case « Lecture automatique » qui active le timer quand elle est cochée, ça permet de suivre l'état de votre port (à condition qu'il change d'état pas trop rapidement, le timer de delphi peut descendre jusqu'à la milliseconde, mais l'oeil humain ne perçoit que 25 images par seconde.)

Remarque : Si vous avez bien fait attention aux cours, vous vous souviendrez que "Busy" est une entrée inversée. Cela signifie qu'elle est à l'état 1 quand elle est au niveau zéro (à la masse) ! Donc si votre port parallèle n'est connecté à rien (qu'il est dans le vide), la valeur renvoyée sera toujours strictement inférieure à 128.

Téléchargement

Téléchargez le programme d'exemple ici