Ce qui suit constitue l'énoncé du travail pratique #2 (TP2).
Étant donné les programmes principaux suivants (disponible sur le site du cours, sous les noms de "TP2Send.cpp" et "TP2Recv.cpp" dans l'archive "TP2Serie.zip"):
// Fichier Recv.cpp #include <iostream.h> #include "Ecran.h" #include "Clavier.h" #include "Serie.h" int main () { bool Termine = false; char c; unsigned short Port; // Variable pour le choix de com1 ou com2 unsigned char Config; // Variable pour la configuration du port int Rangee = 0; int Colonne = 0; Port = Port_Serie(); Config = Port_Serie_Config(); if (Port_Serie_Init(Config, Port)) { Ecran_Initialise(); Message(); while (!Termine) { if (Clavier_Tester_Statut ()) // un caractere a lire { c = Clavier_Lire_Sans_Echo (); if (c == CHAR_ECHAP) { Termine = true; } } if (Port_Serie_Statut(Port)) { c = Port_Serie_Lire_Car(Port); Ecran_Echo(c, Rangee, Colonne); Termine = !Port_Serie_Ecrire_Car(ACK,Port); } } cout << endl << "Merci, au revoir" << endl; } else { cout << "Initialisation du port a echouee" << endl; } } // main () |
// Fichier Send.cpp #include <iostream.h> #include "Ecran.h" #include "Clavier.h" #include "Serie.h" int main() { bool Termine = false; char c; unsigned short Port; // Variable pour le choix de com1 ou com2 unsigned char Config; // Variable pour la configuration du port int Rangee = 0; int Colonne = 0; Port = Port_Serie(); Config = Port_Serie_Config(); if (Port_Serie_Init(Config,Port)) { Ecran_Initialise(); Message(); while (!Termine) { if (Clavier_Tester_Statut()) { c = Clavier_Lire_Sans_Echo(); if (c == CHAR_ECHAP) { Termine = true; } else { if (Port_Serie_Ecrire_Car (c,Port)) { Ecran_Echo(c, Rangee, Colonne); } else { Termine = true; } } } } } else { cout << "Initialisation du port serie a echouee" << endl; } cout << endl << "Au revoir!" << endl; } // main () |
ainsi que le fichier d'en-tête suivant (aussi disponible sur le site du cours, sous le nom de "Serie.h" également dans l'archive "TP2Serie.zip"):
#ifndef SERIE_H #define SERIE_H // Interruption BIOS 14h pour gerer le port serie const int SERIE = 0X14; // Les choix possibles de ports serie const int COM1 = 0 , COM2 = 1 ; // Les choix de vitesse de transmission possibles const int BAUD1200 = 0x04 , BAUD2400 = 0x05 , BAUD4800 = 0x06 , BAUD9600 = 0x07 ; // Les choix de parite possibles const int ODD = 0x01 , EVEN = 0x02 ; // Les fonctions d'entree/sortie a utiliser const int FCT_PORT_SERIE_INIT = 0x00 , FCT_PORT_SERIE_ECRIRE_CAR = 0x01 , FCT_PORT_SERIE_LIRE_CAR = 0x02 , FCT_PORT_SERIE_STATUT = 0x03 ; const char ACK = 0; // le caractere a envoyer pour confirmer la // reception // Fonction: unsigned short Port_Serie_Choix () // Demade le numero du port serie a utiliser // Retourne la valeur qui represente le numero du port unsigned short Port_Serie(); // Fonction: unsigned char Port_Serie_Config () // Demade des parametres d'initialisation du port serie // Retourne l'octet qui represente les parametres d'initialisation unsigned char Port_Serie_Config(); // Fonction: Port_Serie_Init (unsigned char Config, unsigned short Port) // Initialise le port serie // a l'aide de la fonction FCT_PORT_SERIE_INIT de // l'interrupt 14h de BIOS. Retourne vrai si le port // est initialise correctement et faux sinon. bool Port_Serie_Init (unsigned char Config, unsigned short Port); // Fonction: Port_Serie_Ecrire_Car (char Car, unsigned short Port) // Envoie un caractere passe en parametre sur le port serie a // l'aide de la fonction FCT_PORT_SERIE_ECRIRE_CAR de l'interrupt // 14h. Retourne true si l'ecriture s'est bien deroulee // et false sinon bool Port_Serie_Ecrire_Car (char Car, unsigned short Port); // Fonction: Port_Serie_Lire_Car (unsigned short Port) // Lit un caractere sur le port serie // a l'aide de la fonction FCT_PORT_SERIE_LIRE_CAR de l'interrupt // 14h. Retourne le caractere lu char Port_Serie_Lire_Car (unsigned short Port); // Fonction: Port_Serie_Statut (unsigned short Port) // Test s'il y a un caractere recu sur le port serie // a l'aide de la fonction FCT_PORT_SERIE_STATUT de l'interrupt 14h // Retourne true s'il y a un caractere sur le port serie et // false sinon bool Port_Serie_Statut (unsigned short Port); #endif // !defined SERIE_H |
De plus, pour les besoins de la cause, nous vous fournissons le fichier objet Ecran.obj que vous devez inclure dans votre projet à la place des fichiers Ecran.cpp et Ecran.h que vous avez eu à compléter pour le projet TP2Ecran.
Vous devrez, à l'aide de Borland C 3.1 (BC3.1):
Vous trouverez aussi dans l'archive "TP2Serie.zip" deux (2) exécutables, soit "Send.exe" et "Recv.exe".
Les programmes "Send.exe" et "Recv.exe" sont le résultat attendu de vos projets (s'ils fonctionnent, c'est là précisément l'exécution à laquelle nous sommes en droit de nous attendre).
Le travail consiste à implanter six (6) sous-programmes permettant de sélectionner et de configurer un port série, l'initialisation du port série, l'écriture sur le port série et la lecture du port série à l'aide de fonctions des services d'interruption du BIOS.
Ces sous-programmes respecteront les prototypes donnés par "Serie.h" (en fait, "Serie.cpp" devrait inclure "Serie.h").
Chaque sous-programme devra faire appel à une fonction du service d'interruption 14h. Vous devrez inclure le fichier d'en-tête "dos.h" et faire usage de la fonction "int86()" de même qu'au type "union REGS".
Note: | au besoin, n'hésitez pas à faire usage de l'aide en ligne de BC3.1. |
Dans tous les cas, vous devrez:
Cette fonction initialise le port de communication série avec une vitesse, une parité, une longueur de mot et un nombre de bits stop. Les paramètre de configuration seront ceux dont l'octet se trouve le registre "AL" au moment de l'appel de l'interruption. Le registre "DX" doit contenir le numéro de port de communication série (COM1 ou COM2) au moment de l'appel de l'interruption.
Note: | référez-vous au document "COMMUNICATION--UTILISATION DU PORT SÉRIE" pour de plus amples information sur la configuration du port de communication série. |
Cette fonction écrit un caractère sur le port série spécifié, en envoyant l'état courant du port. Le caractère à écrire sera celui dont le code ASCII se trouve dans le registre "AL" au moment de l'appel de l'interruption. Le registre "DX" doit contenir le numéro de port de communication série (COM1 ou COM2) au moment de l'appel de l'interruption.
Cette fonction lit un caractère sur le port série spécifié. Le code ASCII du caractère lu se trouvera dans le registre "AL" après l'appel de l'interruption. Le registre "DX" doit contenir le numéro de port de communication série (COM1 ou COM2) au moment de l'appel de l'interruption.
Cette fonction vérifie la présence d'un caractère sur le port série spécifié. S'il y en a effectivement un de disponible, le bit 0 du registre "AH" sera "allumé" (contiendra la valeur 1) après l'interruption. S'il n'y en a aucun de disponible, le bit 0 du registre "AH" contiendra "0" après l'interruption. Le registre "DX" doit contenir le numéro de port de communication série (COM1 ou COM2) au moment de l'appel de l'interruption.
Bonne chance!