Skip to Content

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 :

  •  SPP : Standard Parrallel Port
  •  EPP : Enhanced Parrallel Port
  •  ECP : Extended Capabilities Port

    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) :

  •  0x378 (port appelé Data) utilisable en sortie sur 8 lignes
  •  0x379 (port appelé Etat) utilisable en entrée sur 5 lignes
  •  0x37a (port appelé Cont) utilisable en sortie sur 4 lignes

    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 :

  •  un 0 logique correspond à 0 volt (la masse) (0 à 0,7 volt)
  •  un 1 logique correspond à +5 volts (de 2,4 volts à 5 volts)

    Les Entrées :

    En logique TTL :

  •  une entrée reliée au 5v par une résistance de rappel de 10k retourne un 1 logique.
  •  une entrée reliée au 0 volt par une résistance de 1K retourne un 0 logique.
  •  une entrée qui reste "en l’air" retourne un 1 logique.

    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.

  •  Le montage est entièrement dans le boitier (sobriété )
  •  La commande est isolée du secteur par un opto-coupleur puis par un relais (sécurité )
  •  L’isolation est double et dépasse dans tout les cas 1500 volts. ( tranquilité )

    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 :

  •  out(octet,adresse) pour écrire sur un port
  •  in(adresse) pour lire un port

    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 :

  •  gcc write378.c -o write378
  •  gcc read379.c -o read379

    Modifier leur droits pour que le propriétaire soit root :

  •  chown root.root write378
  •  chown root.root read379

    Modifier leurs droits pour qu’ils deviennent -rwsr-sr-x (bien positionner "s" )

  •  chmod 6755 write378
  •  chmod 6755 read379

    Ecrire les scripts allume.sh et lecture.sh

    Positionner leurs droits en exécutable par tous

  •  chmod 755 allume.sh
  •  chmod 755 lecture.sh

    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.gif1.06 Ko
    secteur.gif2.13 Ko
    hard03.gif1.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 :

  •  avec Redhat = [asm/io.h] ou [sys/io.h] (mais pas les deux)
  •  avec debian = [sys/io.h]
    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 ;)