Introduction
Malgré son grand âge, le port série est très largement utilisé par les ordinateurs pour communiquer avec des périphériques (imprimante, souris, modem...) car il est très simple à utiliser et ne nécéssite que peu de fils. Plus difficile à mettre en oeuvre que le port parallèle, il se révèle cependant plus puissant et plus universel.
Le support physique utilisé
Le connecteur utilisé à l'origine pour le port série est le connecteur DB25, mais depuis quelques
années, on trouve de plus en plus de connecteurs DB9. Au niveau du PC, on utilise des connecteurs
mâles, tandis qu'au niveau du périphérique, on trouve des connecteurs femelles.
Quelque soit le type de connecteur utilisé, une liaison série comporte 8 signaux différents, plus une ou deux masses :
Broche DB9 | Broche DB25 | Nom | DTE | DCE | Description |
---|---|---|---|---|---|
x | 1 | PG | x | x |
Masse de protection (PG = Protecting Ground)
Ne pas utiliser comme masse du signal ! |
3 | 2 | TD | S | E | Transmission de données (TD = Transmit Data) |
2 | 3 | RD | E | S | Réception de données (RD = Receive Data) |
7 | 4 | RTS | S | E | Demande d'autorisation à émettre (RTS = Request To Send) |
8 | 5 | CTS | E | S | Autorisation d'émettre (CTS = Clear To Send) |
6 | 6 | DSR | E | S | Prêt à recevoir (DSR = Data Set Ready) |
5 | 7 | SG | E | S | Masse du signal (SG = Signal Ground) |
1 | 8 | DCD | E | S | Détection de porteuse (DCD = Data Carrier Detect) |
4 | 20 | DTR | S | E | Équipement prêt (DTR = Data Terminal Ready) |
9 | 22 | RI | E | S | Détection de sonnerie (RI = Ring Indicator) |
DTE signifie Data Terminal Equipment et correspond en général au PC, alors que DCE signifie Data Communication Equipement et correspond au périphérique.
D'un point de vue électrique, les différents signaux présents sur le port série sont définis par la norme RS232. Afin d'avoir une plus grande immunité au parasites, on utilise des tensions comprises entre -25 et +25V. Une tension comprise entre -3V et -25V représente un 1 logique (mark), alors qu'une tension comprise entre +3V et +25V représente un 0 logique (space).
Certains périphériques comme des microprocesseurs utilisent une logique TTL, bien connue des électroniciens. Afin de passer d'une logique RS232, dite inversée, à une logique TTL, certains fabricants ont développé des circuits intégrés spécifiques. Par exemple, le fabricant Maxim produit un composant appelé MAX232 pour adapter ces niveaux.
Le protocole utilisé
L'interruption 14H du BIOS
L'interruption 14h du BIOS propose plusieurs fontions pour la communication série du PC. A chaque appel, le registre AH doit contenir le numéro de l'interface. La première interface (COM1) possède le numéro 0. Notez que l'interruption vérifie la validité de la valeur passée à DX. Les fonctions ne sont pas executées si le numéro de l'interface n'est pas valide.
Fonction 0 - Initialisation du port série
- Entrée :
- AH = numéro de la fonction, c'est à dire 0
- DX = numéro de l'interface (0 à 3)
- AL = paramètres de configuration
- Sortie :
- AH = état de l'interface
- AL = état du modem
La première interface série porte ne numéro 0, la seconde le numéro 1, etc ...
Les paramètres de configuration (octet dans AL lors de l'appel) sont les suivants :
-
bits 7 - 5 : vitesse de transmission
000 = 110 bauds
001 = 150 bauds
010 = 300 bauds
011 = 600 bauds
100 = 1200 bauds
101 = 2400 bauds
110 = 4800 bauds
111 = 9600 bauds -
bits 4 - 3 : parité
00 = pas de parité
01 = parité impaire
10 = pas de parité
11 = parité paire -
bit 2 : nombre de bits de stop
0 = 1 bit de stop
1 = 2 bits de stop si la taille de données es supérieure à 5
1 = 1,5 (un et demi) bit de stop si la taille des données est 5 -
bits 1 - 0 : taille des données
00 = 5 bits
01 = 6 bits
10 = 7 bits
11 = 8 bits
En sortie, le registre AL retourne le contenu du registre d'état du modem de l'UART :
- bit 7 : liaison avec le modem récepteur établie
- bit 6 : le téléphone sonne
- bit 5 : modem activé
- bit 4 : modem prêt à émettre
- bit 3 : le bit 7 a changé
- bit 2 : le bit 6 a changé
- bit 1 : le bit 5 a changé
- bit 0 : le bit 4 a changé
En sortie, le registre AH retourne le contenu du registre d'état de ligne de l'UART :
- bit 7 : dépassement de temps imparti ou TIME OUT
- bit 6 : registres de transmissions vides (TEMT = Transmitter EMpTy)
- bit 5 : registre de transmission vide (THRE = Transmitter Holding Register Empty)
- bit 4 : interruption Break (BI = Break Interrupt)
- bit 3 : erreur de protocole (FE = Frame Error)
- bit 2 : erreur de parité (PE = Parity Error)
- bit 1 : donnée écrasée (OE = Overrun Error)
- bit 0 : donnée reçue et prête (DR = Data Ready)
Le bit 7 fournit une information particulière qui n'est pas associée à une ligne de communication. En effet si une erreur est détectée, l'interruption 14h exécute un certain nombre de nouvelles tentatives avant de reandre son véritable verdict. Si toutes les tentatives échouent, l'état de l'interface série est alors retourné dans AH, dont le bit 7 est mis à 1 pour signaler que le temps imparti est dépassé.
Fonction 1 - Emission d'un caractère
- Entrée :
- AH = numéro de la fonction, c'est à dire 1
- DX = numéro de l'interface (0 à 3)
- AL = caractère à émettre
- Sortie :
- AH = état de l'interface (voir fonction 0)
Fonction 2 - Réception d'un caractère
- Entrée :
- AH = numéro de la fonction, c'est à dire 2
- DX = numéro de l'interface (0 à 3)
- Sortie :
- AH = état de l'interface (voir fonction 0)
- AL = caractère reçu (si le bit 7 de AH est à 0)
Fonction 3 - Test de l'état de la communication
- Entrée :
- AH = numéro de la fonction, c'est à dire 3
- DX = numéro de l'interface (0 à 3)
- Sortie :
- AH = état de l'interface (voir fonction 0)
- AL = état du modem (voir fonction 0)
Remarque 1 : Les fonctions 1, 2 et 3 de l'interruption 14h peuvent affecter le registre de contrôle du modem de l'UART. Si vous souhaitez gérer ce registre de manière spécifique, il est préférable de manipuler directement l'UART, sans passer par l'interruption 14h. Voir paragraphe suivant.
Remarque 2 : Cette interruption est maintenant dépassée, il faut l'utiliser uniquement dans le cadre d'une programmation sous DOS. Dans le cas contraire, il est conseillé d'utiliser la fonction du système d'exploitation utilisé ou un accès direct à l'interface série via les ports d'entrée/sortie. Pour un système POSIX (par exemple GNU/Linux), voir le paragraphe programmation POSIX avec TERMIOS.
Les ports d'entrée/sortie des interfaces séries
Dans beaucoupe de cas, l'interruption 14h ne sera pas suffisante pour piloter un périphérique connecté à l'interface série. Il faut alors gérer directement les ports d'E/S.
Cette interface se programme à l'aide de huit registres différents. Si le PC possède plusieurs ports série, il y aura autant de groupe de huits registres que de nombre de ports série.
En général, le première interface série est associée au ports 3f8h à 3ffh, et la seconde aux ports 2f8h à 2ffh. Néanmoins, ces valeurs ne sont pas universelles. Pour en connaître la valeur, le BIOS possède une table à l'adresse 0040h:0000h comportant les adresses de base des quatres interfaces série :
- 0040h:0000h : adresse de base de l'interface série n°1 (zéro si inexistante)
- 0040h:0002h : adresse de base de l'interface série n°2 (zéro si inexistante)
- 0040h:0004h : adresse de base de l'interface série n°3 (zéro si inexistante)
- 0040h:0006h : adresse de base de l'interface série n°4 (zéro si inexistante)
Les adresses ci-dessus sont remplies par le POST (Power On Self Test) au démarrage de l'ordinateur. Le POST ne laisse jamais d'intervalle. Les numéros des ports série peuvent être redéfinis en changeant ces valeurs.
Venons en maintenant à la description des différents registres.
Adresse de base : registre de transmission et de réception
En lecture, ce registre est un tampon qui contient le dernière caractère reçu.
En écriture, ce registre est un tampon, dans lequel doit être placé un caractère à émettre.
Adresse de base + 1 : registre d'autorisation des interruptions
Ce registre conserve un masque des interruptions autorisées. Lorsqu'un des bits 0 à 3 est mis à 1, l'UART est autorisé à effectuer une demande d'interruption si la condition correspondante est réalisée :
- bits 7 - 4 : inutilisés (0)
- bit 3 : une condition de changement d'état peut être lue. Priorité 4
- bit 2 : une condition de d'erreur peut être lue dans le registre d'état de ligne. Priorité 1 (maximale).
- bit 1 : le registre de transmission est vide et peut accepter un nouveau caractère. Priorité 3.
- bit 0 : un caractère reçu est disponible dans le registre de réception. Priorité 2.
Notez que, sur le PC, l'UART n'exécute une demande d'interruption que si le bit 3 du registre de contrôle du modem est mis à 1. Voir le commentaire concernant ce registre.
Adresse de base + 2 : registre d'indentification des interruptions
Il ne faut pas écrire dans ce registre. Il peut être lu afin d'identifier le niveau de priorité d'une interruption demandée par l'UART. Lorsque le bit 0 est à 1, aucune demande d'interruption n'est en cours. Si une interruption est en attente, le niveau de priorité est retourné dans les bits 1 et 2.
Adresse de base + 3 : registre de contrôle de ligne
Ce registre de contrôle permet de spécifier les différentes caractéristiques de la communication série.
-
bit 3 : parité
0 = pas de parité
1 = un bit de parité -
bit 2 : nombre de bits de stop
0 = 1 bit de stop
1 = 2 bits de stop si la taille de données es supérieure à 5
1 = 1,5 (un et demi) bit de stop si la taille des données est 5 -
bits 1 - 0 : taille des données
00 = 5 bits
01 = 6 bits
10 = 7 bits
11 = 8 bits
Adresse de base + 4 : registre de contrôle du modem
Ce registre contrôme l'interface avec le modem :
- bits 7 - 5 : inutilisés (0)
- bit 4 : ce bit doit être mis à 0. S'il est à 1, l'UART entre en "mode diagnostique"
- bit 3 : défini l'état de la sortie OUT2 de l'UART
- bit 2 : défini l'état de la sortie OUT1 de l'UART
- bit 1 : défini l'état de la ligne RTS
- bit 0 : défini l'état de la ligne DTR
Remarque : L'interface du PC utilise la ssortie OUT2 pour valider l'autorisation des interruptions électronique par les UART (compatibilité Hayes). Le bit 3 doit donc être mis à 1 pour activer les demandes d'interruption.
Adresse de base + 5 : registre d'état de ligne
Il est conseillé de ne jamais écrire dans se registre. Il peut être lu afin de connaître l'état courant de la ligne série.
- bit 7 : inutilisé (0)
- bit 6 : Registres de transmissions vides (TEMT = Transmitter EMpTy)
- bit 5 : Registre de transmission vide (THRE = Transmitter Holding Register Empty)
- bit 4 : Interruption Break (BI = Break Interrupt)
- bit 3 : Erreur de protocole (FE = Frame Error)
- bit 2 : Erreur de parité (PE = Parity Error)
- bit 1 : Donnée écrasée (OE = Overrun Error)
- bit 0 : Donnée reçue et prête (DR = Data Ready)
Remarque : Les bits 1 à 4 signalent des états d'erreur et peuvent provoquer une demande d'interruptions si le bit 2 du registre d'autorisation des interruptions est à 1. Les bits 0 et 5 peuvent également déclencher une demade d'interruption si le registre d'autorisation des interruptions le permet.
Adresse de base + 6 : registre d'état du modem
Ce registre donne l'état des lignes de contrôle en provenance du modem et signale les éventuels changements survenus sur ces lignes depuis la dernière lecture de ce registre.
- bit 7 : état de CD
- bit 6 : état de RI (détection de sonnerie)
- bit 5 : état de DSR
- bit 4 : état de CTS
- bit 3 : CD a changé d'état
- bit 2 : RI a changé d'état
- bit 1 : DSR a changé d'état
- bit 0 : CTS a changé d'état
Remarque : Les bits 0 à 3 signalent des changement d'état et peuvent provoquer une demande d'interruption si le bit 3 du registre d'autorisation des interruptions est à 1.
Adresse de base + 7 : registre inutilisé (Scratch)
Programmation POSIX avec TERMIOS
La programmation des ports série sous les systèmes d'exploitation POSIX (par exemple GNU/Linux) utilise l'interface TERMIOS. Le principe est d'appliquer un ensemble de paramètres définis dans une structure termios à un descripteur de fichier (file-descriptor) ouvert sur un terminal donné (par exemple un ligne série). Lorsque le descripteur de fichier est correctement configuré, on peut l'exploiter grâce aux appels systèmes standards, read, write, select, etc.
Le but de ce paragraphe n'est pas de fournir une description complète de termios : vous pouvez pour cela vous référer au man termios ou au divers documents consacrés au sujet.
Le premier exemple ci-dessous permet de forcer le raccrochage (hangup) d'un modem en faisant chuter le signal DTR. Dans la définition de l'interface POSIX des terminaux, cela s'effectue simplement en positionnant la vitesse à 0 (valeur B0) :
#include <fcntl.h> #include <termios.h> main(int argc, char *argv[]) { int fd; struct termios tty, old; /* Ouverture du device */ if ((fd = open(argv[1], O_RDWR)) < 0) { perror(argv[1]); exit(1); } /* Lecture des paramètres */ tcgetattr(fd, &tty); tcgetattr(fd, &old); /* On passe la vitesse à 0 ==> hangup */ cfsetospeed(&tty, B0); cfsetispeed(&tty, B0); /* On applique le nouveau paramètrage pendant 1s */ tcsetattr(fd, TCSANOW, &tty); sleep(1); /* On revient à l'ancien et on quitte */ tcsetattr(fd, TCSANOW, &old); close(fd); }
Par défaut, une ligne série est ouverte en mode canonique. Le mode canonique consiste à traiter les entrées d'un terminal comme une ligne terminée par un séparateur (le plus souvent LF : line-feed correspondant à la touche Entrée). Cela signifier que le programme applicatif ne pourra disposer de la saisie que lorsque le séparateur sera reçu. Dans le mode canonique, un certain nombre de caractères de contrôle sont disponibles (effacement, etc.).
Ce comportement est adapté au traitement d'un terminal réel avec un dialogue opérateur mais il n'est pas utilisable dans le cas du dialogue avec un équipement de type modem, par exemple. Le deuxième exemple permet donc de positionner une ligne série en mode direct (raw) et donc d'inhiber le mode canonique :
/* Fixe un device en mode RAW */ void raw_mode (int fd, struct termios *old_term) { struct termios term; tcgetattr(fd, &term); /* Sauve l'ancienne config dans le paramètre */ tcgetattr(fd, old_term); /* mode RAW, pas de mode canonique, pas d'écho */ term.c_iflag = IGNBRK; term.c_lflag = 0; term.c_oflag = 0; /* Controle de flux hardware (RTS/CTS) */ term.c_cflag |= (CREAD | CRTSCTS); /* 1 caractère suffit */ term.c_cc[VMIN] = 1; /* Donnée disponible immédiatement */ term.c_cc[VTIME] = 0; /* Inhibe le contrôle de flux XON/XOFF */ term.c_iflag &= ~(IXON | IXOFF | IXANY); /* 8 bits de données, pas de parité */ term.c_cflag &= ~(PARENB | CSIZE); term.c_cflag |= CS8; /* Gestion des signaux modem */ term.c_cflag &= ~CLOCAL; tcsetattr(fd, TCSANOW, &term); }
Un descripteur de fichier sur un port série sera ouvert par une ligne du type fd = open(device_name, OR_RDWDR). Par défaut cette ligne est ouverte en mode bloquant, ce qui peut parfois poser des problèmes dans le cas de l'utilisation du device /dev/ttySx. On peut alors ouvrir le device en mode non bloquant par l'appel : fd = open(device_name, OR_RDWDR | O_NDELAY).
Protocoles de quelques périphériques RS232
Les souris
Les modems
La plupart des modems se laissent commander par le jeu de commande HAYES. Chaque ligne de commande commence par AT, suivie d'une des nombreuses commandes listées ici et d'un retour chariot. Cette liste n'est pas exhaustive ; la plupart des modems ont leur propres commandes, mais celles listées ici sont disponibles avec la plupart des modems.
- A/
- Répéter la dernière commande (non précédé de AT)
- A
- Décrocher - Engager une connexion sans appel
- B
-
Selectionner le standard de communication :
- B0 - CCITT
- B1 - Bell
- C
-
Active ou désactive la porteuse :
- C0 - porteuse activée
- C1 - porteuse désactivée
- D
-
Composer un numéro. Normallement suivi par :
- T - numérotation par tonalités
- P - numérotation par impulsions
- rien - numérotation en fonction de la configuration (voir ATP/ATT)
puis par une séquence composée des caractères suivants :- 0-9 - the numbers to be dialed
- W - attendre la tonalité
- , - attendre 2 secondes
- @ - attendre 5 secondes
- ! - flash (racrocher la ligne pendant une demi-seconde)
- ; - retour au mode commande après numérotation
- R - démarrer la connexion juste après la numérotation (par ex. ATDPR équivaut à ATA)
- S=n - Sélection du numéro mémorisé (ATDS sélectionne le numéro mémorisé sous S=0, ATDS=1 le numéro mémorisé sous S=1, etc.)
Si vous entrez juste ATD, le modem décroche sans numéroter. - E
-
Active ou désactive l'écho local
- E0 - commandes sans écho
- E1 - commandes avec écho
- H
- Raccrocher
-
L : Contrôle du volume ; suivi par 0-3 (0 pour le volume le plus faible, 3 pour le plus élevé)
-
M : Monitor
M0 - Speaker off
M1 - Speaker on while dialing and establishing a connection
M2 - Speaker always on
M3 - Speaker on while establishing a connection
-
O : Switch to data mode
O0 - promptly
O1 - with retrain (reduction of the data rate)
-
P : Pulse dial
-
Q : Responses to commands on/off
Q0 - on
Q1 - off
-
S : Set/read internal register, eg.
S17=234 set reg. 17 to 234
S17? read reg. 17
-
T : Tone dial
-
V : Verbose mode on/off
V0 - short responses
V1 - full responses
-
X : Phone tones recognition on/off
X0 - Ignore busy sign, don't wait for dial tone, and just answer with CONNECT" when a connection has been established (other settings produce more detailed messages)
X1 - Ignore busy sign, don't wait for dial tone, but give full connect message
X2 - Ignore busy sign but wait for dial tone
X3 - Don't ignore busy sign, but don't wait for dial tone
X4 - Don't ignore anything
-
Y : Break setting
Y0 - Don't hang up when break signal is detected
Y1 - Hang up when break is detected (&D2, &M0)
-
Z : Initialize modem
Z - Default parameters
Z0 - Setting 0
Z1 - Setting 1
-
&C : DCD mode
&C0 - always 1
&C1 - DCD according to carrier
-
&D : DTR mode
&D0 - ignore DTR
&D1 - switch to command mode when DTR goes 0
&D2 - hang up if DTR goes 0
&D3 - initialize modem when DTR goes 0
-
&F : Set operation mode
&F0 - according to Hayes, no data protocol
&F1 - according to Microcom; MNP1-4 or MNP5 as specified by %C
&F2 - according to Sierra; MNP1-4 or MNP5 as specified by %C
&F3 - according to Sierra, V.42 or V.42bis as specified by %C
These are the default settings:
&F0 - B0, E1, L2, M1, , Q0, V1, Y0, X1, &C1, &D0, &G0, &R0, &S0, S0=0, S1=0, S2=43, S3=13, S4=10, S5=8, S6=2, S7=30, S8=2, S9=6,S10=14, S11=75, S12=50, S14=AAh, S16=80h, S21=20h, S22=76h, S23=7, S25=5, S26=1, S27=40h
&F1 - \A3, \C0, \E0, \G0, \K5, \N1, \Q0, \T0, \V0, \X0, %A0, %C1, %E1, %G0, &G1, S36=7h, S46=138h, S48=128h, S82=128h
&F2 - \A3, \C2, \E0, \G1, \K5, \N3, \Q1, \T0, \V1, \X0, %A13, %C1, S36=7h, S46=138h, S48=128h, S82=128h
&F3 - \A3, \C0, \E0, \G0, \K5, \N3, \O1, \T0, \V1, \X0, %A0, %C1, %E0, S36=7h, S46=138h, S48=7h, S82=128h
-
&G : Guard tone
&G0 - off
&G1 - 550 Hz
&G2 - 1800 Hz
-
&K : Data flow control
&K0 - none
&K3 - bidirectional RTS/CTS handshaking
&K4 - bidirectional XON/XOFF
&K5 - unidirectional XON/XOFF
-
&M : Synchronous/asynchronous operation
&M0 - asynchronous (the usual thing)
&M1 - command mode asynchronous, data mode synchronous.
&M2 - switch to synchronous mode, start dialing after DTR 0->1
&M3 - switch to synchronous mode, don't dial
-
&Q : Further specification of the communication
&Q0 to &Q3 - no V.42bis
&Q5 - V.42bis
&Q6 - V.42bis off, buffer data
-
&R : CTS mode
&R0 - CTS follows RTS with the delay time of S26
&R1 - CTS is 1 if the modem is in the data mode
-
&S : DSR mode
&S0 - DSR always 1
&S1 - according to CCITT V.24
-
&T : Test
&T0 - normal operation (no test)
&T1 - local analog loopback
&T3 - local digital loopback
&T4 - accept distant digital loopback
&T5 - ignore distant digital loopback
&T6 - start distant digital loopback
&T7 - start distant digital loopback and self test
&T8 - start distant analog loopback and self test
-
&V : Show modem status
-
&Wn : Save actual configuration (some modems only). Setting can be
restored with ATZn. n normally ranges between 0 and 1.
The following parameters are stored:
B, C, E, L, M, /T, Q, V, X, Y, &C, &D, &G, &R, &S, &T4/&T5, S0, S14, S18, S21, S22, S25, S26, S27
-
&X : Specify clock source for synchronous operation
&X0 - modem generates clock
&X1 - modem synchronizes with local clock
&X2 - modem synchronizes with distant clock
-
&Y : Define default setting (see &W and Z)
&Y0 - setting 0 is default
&Y1 - setting 1 is default
-
&Z : Store phone number in diary
&Zn=XXXXXX stores phone number XXXXXX under index n, where XXXXXX can be up to 30 digits and n ranges between 0 and 3.