Les entrées/sorties sur le port parallele
LES ENTREES/SORTIES SUR LE PORT PARALLELE
Le port IEEE 1284 dit aussi "parallèle" ou "imprimante" ou "centronic" est présent sur la plupart des micro-ordinateurs de type compatible IBM-PC.
Il peut facilement être détourné de son rôle d’impression et être utilisé comme port d’entrées/sorties universel.
Le connecteur est un DB25 femelle.
Au niveau du Bios, ce port peut être configurer dans 3 modes :
Seul sera traité ici le mode SPP.
Généralement, sur les Bios modernes, les deux autres modes basculent automatiquement en SPP quand ils reçoivent une commande destinée à un port SPP. Donc tout va bien pour nous.
L’aspect Matériel
Dans le plan d’adressage du PC, l’ensemble des signaux présents sur le connecteur occupe 3 adresses. Généralement c’est les adresses (pour lpt0) :
Des informations sur ce port (et tous les ports en général) peuvent être obtenues en visitant /proc/interrupts et /proc/ioports
Voilà la liste des 25 lignes présentes sur le connecteur DB25 :
1 : => sortie (Cont 0 logique négative)
2 : => sortie (Data 0 logique positive)
3 : => sortie (Data 1 logique positive)
4 : => sortie (Data 2 logique positive)
5 : => sortie (Data 3 logique positive)
6 : => sortie (Data 4 logique positive)
7 : => sortie (Data 5 logique positive)
8 : => sortie (Data 6 logique positive)
9 : => sortie (Data 7 logique positive)
10 : <= entrée (Etat 6 logique positive)
11 : <= entrée (Etat 7 logique négative)
12 : <= entrée (Etat 5 logique positive)
13 : <= entrée (Etat 4 logique positive)
14 : => sortie (Cont 1 logique négative)
15 : <= entrée (Etat 3 logique positive)
16 : => sortie (Cont 2 logique positive)
17 : => sortie (Cont 3 logique négative)
18 à 25 = masse
Attention : au démarrage de la machine, les sorties peuvent être dans un état quelconque. il est donc très imprudent de connecter un périphérique sur ce port et de l’alimenter tant que le bios n’a pas stabilisé les sorties.
D’un point de vue électronique
La normalisation du port IEEE 1284 prévoit des signaux TTL :
Les Entrées :
En logique TTL :
Les entrées du port IEEE 1284 retourne donc un 1 par défaut si elle ne sont pas polarisées. Cet état n’étant pas très stable, il est conseillé d’utiliser systématiquement des résistances de polarisation (reliées au 5V de préférence)
Dans le cas où le port doit travailler en ambiance "difficile", il est conseillé de protéger les entrées avec des opto-coupleur :
Pour utiliser une entrée opto-couplée, il suffit de la relier à la masse à travers un interrupteur ou un transistor. Quand l’interrupteur se ferme ou quand le transistor conduit, le niveau zéro (la masse) remonte, allume la led de l’optocoupleur qui devient passant et porte l’entrée au potentiel 0 (par défaut, une entrée débranchée est donc à 1).
Les sorties :
En théorie, une sortie TTL ne peut délivrer qu’un niveau logique. En pratique, cette tension de sortie peut être chargée de façon à débiter un courant faible de l’ordre de 10mA maximum. C’est suffisant pour allumer une led reliée à la masse par une résistance de 470 ohm ( (5v - 1,5) / 0,01A = 350 ohm minimum )
Ce courant peut commander un transistor en commutation ou un opto-coupleur.
Le montage suivant à été dévellopé au collège Camille Claude de Chevigny St Sauveur.
(http://perso.wanadoo.fr/college.claudel.chevigny/techno/eclaire/secteur.htm)
Il permet de commander un appareil en 220 volts grâce à n’importe quelle petite sortie binaire (port parallele, port serie...)
Les composants sont très ordinaires et le prix de revient est ridicule.
La mise en boite se fait dans un boitier du type "adaptateur secteur" avec une prise mâle secteur et une prise femelle en sortie.
L’aspect logiciel.
Le PC ayant une architecture basée sur le processeur i386, on peut faire appel directement aux ports d’entrée/sortie. Selon le système d’exploitation utilisé, il est éventuellement possible de passer par des fonctions systèmes. Cette méthode est respectueuse du système mais elle oblige souvent à adapter l’écriture du
logiciel aux différentes et successives version de systèmes. Elle ne sera donc utilisée que dans le cas ou on connais précisément la version du système utilisée.
en assembleur, on utilise les fonctions :
en C, on utilise :
#include
#include
int data,etat,cont,octet;
int main()
{
unsigned int lu;
data=0x378; /* pour le port lpt0 */
etat=0x379;
cont=0x37a;
if(ioperm(data,3,1))
{perror("ioperm"); exit(1);}
octet=0xFF;
outb(octet, data);
lu=inb(etat);
printf("%X", lu);
exit(0);
}
en FreePascal, on utilise :
Program test_IO;
uses Linux,crt;
var Octet : byte;
const Data=$378; /* pour le port lpt0 */
Stat=$379;
Cont=$37A;
begin /* main */
if not(IOperm(Data,3,1)) then exit;
Octet := $FF
writeport(Data,Octet); //octet -> port(Data)
readport(Stat,Octet); //port(Etat) -> octet
end;
Sous Linux, les commandes IOperm, inb et outb ne peuvent être utilisées que par l’utilisateur root.
Il existe différentes façons de contourner cette limitation. Une méthode relativement simple consiste à écrire un petit programme très limité capable uniquement d’effectuer des entrées/sorties. Ce programme appartient à root et est doté du bit SUID. Il peut être appelé par n’importe quel programme utilisateur qui lui passera les paramètres à échanger avec le port parallèle. Il faut écrire ce mini programme avec soin afin d’éviter toute faille de sécurité.
Marche a suivre (exercice pratique)
Écrire les programmes write378.c et read379.c
Les compiler :
Modifier leur droits pour que le propriétaire soit root :
Modifier leurs droits pour qu’ils deviennent -rwsr-sr-x (bien positionner "s" )
Ecrire les scripts allume.sh et lecture.sh
Positionner leurs droits en exécutable par tous
Faire des tests avec une entrée et une sortie simplifiée.
--------------
- write378 -
--------------
#include
#include
#include
const unsigned int DATA=0x378;
int octet;
int main(int argc, char *argv[])
{
if(ioperm(DATA,1,1)) {perror("ioperm"); exit(1);}
if (argc != 2) {perror("erreur de parametres"); exit(1);}
octet=atoi(argv[1]);
outb(octet,DATA);
return(0);
}
--------------
- read379 -
--------------
#include
#include
#include
const unsigned int ETAT=0x379;
int octet;
int main(int argc, char *argv[])
{
if(ioperm(ETAT,1,1)) {perror("ioperm"); exit(1);}
octet=inb(ETAT);
printf("%d",octet);
return(0);
}
--------------
- allume.sh -
--------------
#!/bin/bash
# argument $1 = tempo en secondes
echo
echo ECLAIRAGE : ON
octet='255'
./write378 $octet
sleep $1
echo
echo ECLAIRAGE : OFF
octet='0'
./write378 $octet
echo
--------------
- lecture.sh -
--------------
#!/bin/bash
echo Lance lecture
echo
octet=`./read379`
echo "octet lu : "$octet
echo
if [ "$octet" -gt 127 ]
then echo 1 ;
else echo 0
fi
echo
echo fin de lecture
echo
--------------
Fichier attaché | Taille |
---|---|
hard02.gif | 1.06 Ko |
secteur.gif | 2.13 Ko |
hard03.gif | 1.73 Ko |
Commentaires
Les entrées/sorties sur le port parallele
Ok, tu as probablement raison dans ton cas.
Je viens de faire l’essai : avec une Redhat, l’inclusion [asm/io.h] est suffisante.
Mais si je fais la même chose avec une debian, il me donne un warning.
Par contre, avec une Redhat, si je met [sys/io.h], j’ai un conflit avec [asm/io.h] que je doit donc supprimer.
Conclusion :
et voilà, tout le monde est content et peut automatiser sa cafetière....
Les entrées/sorties sur le port parallele
C’est super, depuis cet atelier moi aussi je me suis à m’éclater avec mon port parallèle, avec un optocoupleur sur chaque sortie ! Juste une remarque pour le programme en C, ioperm() est déclaré dans sys/io.h, donc il faut ajouter un #include < sys/io.h >, sinon on a un warning et c’est pas très ANSI tout ça ;)