B. Kainka, H.- J. Berndt

Interfaces de PC sous Windows

Avant-propos

Les jours du DOS semblent comptés sur la plupart des PC. Si l'introduction massive de Windows a amélioré le confort des utilisateurs, de nombreux amateurs éclairés et actifs regrettent de ne plus pouvoir accéder à certaines fonctions que DOS mettait sans trop se faire prier à leur disposition. Windows ne donne pas sur l'ordinateur un contrôle aussi complet que DOS.

De nombreuses applications, très simples, ont été mises au point sous DOS pour accéder aux lignes des ports du PC. Il est possible, sous ce système d'exploitation, de connecter sans autres auxiliaires, des diodes électroluminescentes ou de simples interrupteurs (entre autres capteurs) sur un port COM. Ces ports et DOS peuvent également piloter, par l'intermédiaire de circuits élémentaires, toutes sortes d’appareils. Sous Windows, ces solutions simples, semblent, de prime abord, interdites… Cessons là ce bavardage stérile : s'il n'y avait pas de solution sous Windows, ce livre n'aurait pas d'objet. Il se propose de vous montrer comment accéder directement aux divers ports d’un PC sous Windows.

L'un des nombreux objectifs de ce livre est de remettre à l'honneur les montages déjà conçus. Il s'appuie dans une large mesure sur son prédécesseur, J'exploite les interfaces de mon PC mais tient également compte des possibilités qu'offre Windows. En règle générale, ce livre ne fait plus appel qu'à Windows (95 et 98). Les langages de programmation qu'il privilégie sont Visual Basic et Delphi, autrement dit les successeurs sous Windows de GW-Basic, Q-Basic, Turbo Pascal, etc. Ces nouveaux outils permettent d'importer relativement facilement dans Windows les programmes mis au point pour DOS.

Tous nos vœux de succès à vous, lecteurs !

Hans-Joachim Berndt et Burkhard Kainka

Contenu du CD-ROM

Le CD contient des dossiers relatifs à chaque chapitre de ce livre. Vous y trouverez les exemples de programme en Visual Basic 5 (mais traduits et recompilés Visual Basic 6), Delphi 3 (traduits en français et recompilés en Delphi 4) ou Delphi 4, exécutables, avec leurs fichiers source. Le fichier indispensable à l'exécution de ces programmes, PORT.DLL, est présent dans tous les répertoires des fichiers exécutables. Pour votre propre travail avec les programmes, recopiez-le dans le répertoire de Windows de votre PC.

La documentation de PORT.DLL est disponible aux formats Winword 6, Write et TXT, dans le répertoire « Référence ».

En plus des exemples, le CD contient deux programmes d'application complets :

– COMPUNI.EXE : Compact Universal, est un programme d'utilisation de l'interface universelle. Vous le trouverez dans le répertoire Chap8/Delphi4 ;

– SSCANP.EXE : SoundScan permet de transformer la carte son en un oscilloscope complet. Vous le trouverez dans le répertoire Chap14/Delphi3.

Configuration requise pour travailler avec le CD :

PC-486 ou Pentium avec Windows 95/98 ou Windows NT. Logiciels conseillés : Visual Basic 6 et Delphi 4.

 

Sommaire

Avant-propos

1. Introduction

1.1 PORT.DLL

1.2 Appels de DLL dans Visual Basic 6

1.3 Appels de DLL par Delphi

2. Port sériel

2.1 Fonctions DLL pour l'interface sérielle

2.2 Accès RS232 en Visual Basic

2.3 Accès RS232 en Delphi

2.4 Accès par l’intermédiaire d’instructions de port

3. Sorties numériques directes

3.1 Minuterie

3.2 Pilotage de servomoteurs de radiocommande

3.3 Commande de moteur pas à pas

4. Entrées numériques directes

4.1 Enregistrement chronologique d'événements

4.2 Simulation de circuits logiques

5. Numériseur élémentaire

5.1 Mesure de résistance

5.2 Mesure de tension

5.3 Numériseur à quatre voies

5.4 Mesure d’un transistor

6. Mesure de fréquence

6.1 Compteur logiciel

6.2 Mesures de température et d’humidité

6.3 Convertisseur tension-fréquence

6.4 Traceur de fréquence

7. Transmission de données sérielle et synchrone

7.1 Émission sérielle

7.2 Entrée sérielle

7.3 Numériseur lisible en série

8. Interface polyvalente

8.1 Matériel et commande

8.2 Le programme de mesure universel COMPACT

8.3 Testeur automatique de circuits intégrés

9. Port parallèle

9.1 Lignes d’entrée et de sortie

9.2 Ports d’imprimante bidirectionnels

10. Sortie de données en parallèle

10.1 Générateur de fonctions

10.2 Commande de machines élémentaires

11. Extension de port de 16 bits

11.1 Extension de port 8243

11.2 Extension à 32 lignes de port

11.3 Programmateur d'EPROM

12. Bus I2C

12.1 Transfert de données et adressage

12.2 Commande par le port parallèle

12.3 Raccordement au port sériel

12.4 Port d’entrée/sortie PCF8574

12.5 PCF8591 : convertisseur A/N et N/A

12.6 Oscilloscope à mémoire

13. Port de jeu

13.1 Entrées analogiques et numériques

13.2 Mesures de tension

13.3 Contrôle de limite

13.4 Sortie numérique

13.5 Compteur numérique

13.6 Appels au port de jeu par l’intermédiaire des pilotes

14. La carte son

14.1 Enregistrement et reproduction

14.2 Oscilloscope dans Excel

14.3 Oscilloscope dans Delphi

14.4 Émissions sonores calculées

14.5 Test d’audition avec la carte son

15. Cartes de capture vidéo

15.1 Représentation d’une image

15.2 Valeurs de mesure tirées d’informations de couleur

15.3 Mesures de longueur avec un caméscope

16. Transmission sérielle asynchrone

16.1 Lecture des données fournies par une souris sérielle

16.2 Commandes numériques par l’intermédiaire de RS232

16.3 UART à microcontrôleur ST62

16.4 Bus sériel

Bibliographie

Index

1. Introduction

Les expériences de commande ou de contrôle de processus réels à l’aide d’un ordinateur exigent d’abord une liaison convenable de l’ordinateur avec le monde extérieur. Un programme doit être en mesure de récupérer des informations à l’extérieur et de transmettre des signaux de commande à des appareils extérieurs. Les informations traitées peuvent se présenter sous forme binaire et ne connaître que deux états, « oui » ou « non » (0 ou 1), ou comme grandeurs analogiques (grandeurs aux variations continues).

L’ouverture indispensable sur le monde extérieur est offerte par des interfaces (également appelées jonctions, ports : le traducteur de ce manuel utilisera indifféremment « interface » et « port »). Les formes de ports qui se sont imposées dans l’industrie pour les PC sont les suivantes :

Les expériences élémentaires peuvent utiliser directement les interfaces présentes. Il est possible de câbler sur un port sériel des diodes électroluminescentes ou des interrupteurs, sans autres composants, et de réaliser ainsi de nombreux projets intéressants. Le port parallèle offre un plus grand nombre de lignes, adressables directement, et par lesquelles les transmissions sont relativement plus rapides.

Des circuits supplémentaires simples permettent de s’affranchir de nombreuses contraintes. Les détections et mesures de tensions ne réclament que peu de composants supplémentaires, si vous ne mettez pas l’accent sur la rapidité et pouvez compter sur des programmes un peu plus compliqués. Sans grands frais, vous pouvez également envisager des projets demandant de nombreuses lignes d’entrée et de sortie.

Les procédés que présente ce livre fonctionnent, en général, avec peu de matériel mais des programmes qui demandent un peu plus de temps de calcul. Le lecteur doit avoir l’expérience d’un langage de programmation et des connaissances de base en électronique. Les circuits présentés sont, le plus souvent, si simples qu’une platine d’expérimentation suffit à leur montage. Tous les projets proposés sont complets et directement reproductibles. Ils peuvent, de plus, servir de base à d’autres développements dont les procédés, plus compliqués, demanderont parfois le recours à certains instruments de mesure. Les lecteurs intéressés devraient, par exemple, disposer d’un oscilloscope (et savoir s’en servir).

Les langages de programmation qu’utilise ce livre pour le système d’exploitation Windows 95 (ou 98) sont Visual Basic et Delphi 4. Les exemples de programme sont quasiment tous reproduits sur le CD-ROM.

1.1. PORT.DLL

Windows pose de sérieux problèmes d’accès aux ports du PC. Pour les résoudre, nous utilisons ici une bibliothèque de liaisons dynamiques ou DLL (bibliothèque de sous-programmes) universelle, programmée en Delphi 3. Les DLL remplissent les fonctions d’une extension de langage pour différents langages de programmation. La DLL mise au point spécialement pour ce livre, PORT.DLL est sur le CD-ROM. Copiez la dans le répertoire System de Windows où les programmes iront la chercher. A défaut, vous pouvez la copier dans le répertoire du programme .EXE dont vous souhaitez l’exécution.

PORT.DLL remplit les tâches suivantes :

Des systèmes de programmation très différents peuvent utiliser la DLL : ses fonctions sont évidemment accessibles aux langages de programmation de ce manuel mais également à des programmes rédigés en C. Des programmes mis au point sur un système s’exportent ainsi facilement vers d’autres. La DLL peut, de plus, répondre aux appels de macros de Word ou d’Excel (reportez-vous à la section 1.2 et au chapitre 14 pour plus d’informations sur ces possibilités).

En principe, Windows accède aux composants matériels par l’intermédiaire de pilotes (driver). La mise au point d’une DLL générale pour accéder à certains périphériques s’oppose quelque peu à cette façon de voir. Un pilote relève toujours d’un périphérique particulier. Rien n’est prévu ici pour de petites expériences matérielles. La mise au point d’un pilote demande toutefois trop d’investissement et ne concerne pratiquement que des entreprises d’une certaine envergure.

Sous DOS, chaque langage de programmation proposait son instruction de port (INP et OUT sous GWBASIC ; PORT[..] dans Turbo Pascal), qui donnait un accès direct à l’ensemble du matériel du PC. Windows 3.1 laissait encore une certaine latitude et le programmeur pouvait sans trop de peine contourner les limites imposées. La première version de Delphi possédait toujours l’antique instruction PORT.

Les choses ne sont plus si évidentes sous Windows 95. Visual Basic 5 n’offre plus, directement, de possibilité d’accès général aux ports. A partir de Delphi 3, les accès directs aux adresses de port ne sont plus permis qu’en assembleur (code Inline). Ce code est utilisé par la DLL pour restituer à Visual Basic un accès général. Le système d’exploitation ne se laisse cependant pas contourner purement et simplement : avant d’intervenir comme on le souhaite sur un matériel, par exemple, le port dont il relève doit être déclaré en bonne et due forme.

Windows NT enfin semble condamner définitivement les tentatives des amateurs intéressés par le matériel. Le système est conçu, sécurité oblige, pour en interdire tout accès direct. Ne reste que la voie réglementaire, par pilotes interposés. Le matériel en général devrait alors être adressé par l’intermédiaire du port sériel. Tous les accès sont ici possibles, puisqu’ils n’utilisent pas d’accès aux ports mais des routines réglementaires du système.

Insistons sur le fait que ce livre traite avant tout d’expérimentation avec les interfaces (ou ports) de PC. Les programmes présentés ont été mis au point sous Windows95 et Windows98 avec des systèmes à 32 bits (Visual Basic 6 et Delphi 4). Un programme peut ne pas tourner sur certains ordinateurs, si l’installation de son port présente, par exemple, quelques différences avec ce que le programmeur a prévu. Ne parlons pas de futures versions de Windows, qui peuvent encore traiter différemment les accès aux ports. Si vous tentez, sur ces bases, de mettre au point des applications professionnelles, vous risquez fort de devoir fuir sur une île déserte pour échapper aux agressions d’utilisateurs frustrés !

1.2. Appels de DLL dans Visual Basic 6

Nous verrons ici, sur un exemple simple, sans matériel supplémentaire, les principes de base d’utilisation d’une DLL. Le haut-parleur du PC est attaqué par des composants que des instructions de port peuvent commander. Nous disposons ici soit d’une minuterie (timer) pour émettre un son d’une fréquence déterminée, soit d’une ligne de sortie du circuit PIO 8255 du PC. Il suffit, pour produire des sons ici, de successions rapides de mises hors et sous tension d’une ligne. Cette expérience a deux objectifs : nous permettre de voir comment lier une DLL et comment Windows traite le facteur temps.

Nous commandons le haut-parleur par le bit 1 du port B du 8255. Le composant occupe des adresses qui commencent à 60h (96 décimal) dans le domaine des entrées et sorties du PC. Le port B y a l’adresse 97. Le format d'écriture est toujours de 8 bits et mobilise simultanément huit lignes. Nous ne souhaitons toutefois modifier que la deuxième ligne (bit 1) et le port B du PIO commande beaucoup d’autres choses. Nous commencerons par lire le port de façon à n’en modifier qu’un bit. Si vous ne comprenez pas très bien ce que nous disons ici, ne vous inquiétez pas. Le programme est sur le CD-ROM et les interventions sur les interfaces avec l’extérieur sont, pour l’essentiel, beaucoup plus simples.

La DLL propose deux fonctions d’accès spéciales aux adresses de port du PC :

OutPort adr, dat émission de données à une adresse

InPort adr lecture de données à une adresse d'entrée/sortie

Dans Visual Basic, OutPort peut se lier comme Sub (procédure), mais InPort doit se lier comme fonction. Chaque élément d’une DLL est déclaré par l’instruction DECLARE. Les transmissions de données entre Visual Basic et la DLL ne peuvent fonctionner convenablement qu’à l’aide du mot ByVal, c’est-à-dire comme valeurs et non par l’intermédiaire d’une adresse de référence (par défaut). Le système d’exploitation 32 bits Windows95/98 tient compte de la casse (il distingue les capitales et les minuscules) des déclarations. Toutes les fonctions de la DLL sont en capitales, ce que doit respecter le programme appelant. Les déclarations trouvent place dans un module propre (Module1.bas), ajouté au projet SON.

Figure 1.1. Projet son.

Declare Sub OUTPORT Lib "PORT.DLL" (ByVal Adr As Integer,

ByVal Dat As Integer)

Declare Function INPORT Lib "PORT.DLL" (ByVal Adr

As Integer) As Integer

Declare Sub DELAY Lib "PORT.DLL" (ByVal Temps As Integer)

Programme 1.1. Les déclarations de Module1.bas.

L’ensemble du projet dispose maintenant de InPort et OutPort. La procédure Delay est déclarée par la même occasion pour être utilisée un peu plus bas. Une première émission est produite dans une boucle rapide de 100 impulsions rectangulaires à destination du haut-parleur, qui doit alors faire entendre un son. Les émissions vers le port de l’instruction OutPort sont soumises à des manipulations de bits par des fonctions logiques AND et OR, qui permettent de ne modifier qu’une ligne du port à la fois après lecture par l’instruction InPort. Ces fonctions seront également expliquées plus loin.

Le programme utilise une formule simple faite d’un seul bouton « Son ». La ligne du haut-parleur est mise 100 fois alternativement sous tension puis hors tension. Un PC cadencé à 200 MHz ne produira pas de son sans temporisations supplémentaires. Ces temporisations sont produites par des boucles de comptage à 10 000.

Figure 1.2. Fenêtre de programme.

Private Sub Command1_Click()

For n = 1 To 100

OUTPORT 97, (INPORT(97) Or 2)

For t = 1 To 10000: Next t

OUTPORT 97, (INPORT(97) And 253)

For t = 1 To 10000: Next t

Next n

End Sub

Programme 1.2. Emission sonore par le haut-parleur (SON.FRM).

Si l’on clique sur le bouton, le haut-parleur se fait effectivement entendre. La hauteur du son dépend de l’ordinateur sur lequel tourne le programme. Le son n’est pas très clair, il est même franchement « crasseux ». Cela tient à la façon dont Windows gère le temps.

Les temporisations définies par les boucles ne peuvent pas être d’égale durée du fait que Windows traite le programme tout en vaquant à ses autres affaires : il s’occupe de tout à la fois, des demandes de la souris ou d’autres processus en cours. On dit de Windows qu’il ne fonctionne pas en temps réel, qu’il n’est donc pas possible avec ce système d’exploitation de gérer fiablement des processus très rapides. Ce n’est qu’une question de point de vue : tout dépend de la rapidité et de la fiabilité souhaitées. Il est certain que des signaux sonores produits avec la technique de notre exemple ne peuvent pas être propres.

Les boucles de comptage ne sont en tout cas pas les seuls outils de temporisation possibles. Windows fournit de meilleurs moyens de régler des retards de quelques millisecondes. La fonction Delay de la DLL y donne accès. Delay permet d’améliorer sensiblement les émissions sonores. La fréquence du signal de sortie ne peut malheureusement pas dépasser 500 Hz, si l’on change l’état du port une fois par milliseconde.

Private Sub Command1_Click()

For n = 1 To 100

OUTPORT 97, (INPORT(97) Or 2)

DELAY 1

OUTPORT 97, (INPORT(97) And 253)

DELAY 1

Next n

End Sub

Programme 1.3. Émission d’un son à l’aide de Delay (Son2.frm).

Le son produit est de meilleure qualité, bien qu’encore impur comparé à un pur produit électronique. Des améliorations sont encore possibles à l’aide de la procédure RealTime (true) de la DLL (nous le verrons à la section 3.2) mais le résultat obtenu donne déjà une première idée de ce que Windows peut offrir « en temps réel ». Nous pourrions effectuer des recherches plus précises à l’oscilloscope, mais le programme ne s’y prête guère, un programme s’adressant à une ligne de port sériel COM, par exemple, y serait plus propice.

La DLL, en sus d’une fonction Delay permettant d’accéder à la milliseconde, offre également des temporisations réglables par pas de l’ordre de la microseconde. Cette temporisation fait aussi appel en interne à Windows.

Il est préférable de déclarer les appels de DLL dans un module externe BASIC, PORTS.BAS. Nous pourrons insérer par la suite ce module dans tout projet qui utilisera ces déclarations. Le programmeur accède ainsi à toutes les fonctions de la DLL, sans avoir à se préoccuper des conventions exactes des déclarations. Il transmet le fichier PORT.DLL avec le programme compilé (.exe) qu’il faut ensuite copier dans le répertoire de Windows ou celui du programme exécutable.

Declare Function OPENCOM Lib "Port" (ByVal A$) As Integer

Declare Sub CLOSECOM Lib "Port" ()

...

Programme 1.4. Le module PORTS.BAS avec les déclarations nécessaires à VB5.

Il est possible de déclarer les fonctions DLL dans VBA (la version de Visual Basic livrée avec Office de Microsoft®). Les expériences de ce manuel peuvent donc en principe s’effectuer avec Word ou Excel. Les programmes se lancent ensuite comme macro à partir de l’application. A partir des versions 7 de Word et Excel, les déclarations sont celles de Visual Basic 5. L’exemple suivant de production d’un son par le haut-parleur du PC a été programmé sous Word 97. Le chapitre 14 vous donnera d’autres exemples de programmation en VBA.

Figure 1.3. Exemple de macro dans Word 97.

Word 97 permet également l’utilisation d’objets UserForm avec des éléments de commande personnalisés dans ses macros. « Declare » doit être précédé du mot-clé « Private ». Les fonctions et procédures sont de même formées à l’aide de « Private ».

1.3. Appels de DLL par Delphi

Sous Delphi 4, nous accédons également aux ports par l’intermédiaire de PORT.DLL. Le premier exemple reprend le problème précédent de la production d’un son par le haut-parleur du PC. Le programme propose deux boutons, le premier (Son1) sonne à l’aide d’une boucle de comptage, le second (Son2) travaille avec Delay.

Figure 1.4. Premier programme avec Delphi.

Les extensions de DLL sont déclarées comme des procédures et des fonctions normales, dans la même unité, et contiennent, au lieu d’un code de programme, la référence à la DLL externe. Les mots-clé « stdcall » et « external » règlent la transmission des paramètres à la DLL et sont décisifs.

Le choix du type des variables transmises est également important. Sur ce point, notons que les différentes versions de Delphi présentent entre elles des incompatibilités pour certains types d’entiers. Vous ne pourrez pas toujours utiliser sous Delphi 4 un texte source Delphi 3 et réciproquement. Les types Word (16 bits non signés) et DWord (32 bits non signés) ainsi que les Real sont, en revanche, tout à fait compatibles.

Dans Delphi, le nom de l’unité à proprement parler (*.pas) doit être différent de celui du projet (*.dpr). Ce manuel ajoutera donc un P pour « Projet » au nom du fichier projet. Le projet SON1.DPR relève en conséquence de l’unité SON1.PAS. La compilation produit d’abord le programme exécutable SON1P.EXE, que nous renommons SON1.EXE sur le CD.

unit Son1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics,

Controls, Forms, Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Son1: TButton; Son2: TButton;

procedure Son1Click(Sender: TObject);

procedure Son2Click(Sender: TObject);

end;

var

Form1: TForm1;

implementation

{$R *.DFM}

procedure OUTPORT (adr: Word; Valeur: Word);

stdcall; external 'PORT.dll';

function INPORT (adr: Word):Integer;

stdcall; external 'PORT.DLL';

procedure DELAY (ms: Word);

stdcall; external 'PORT.DLL';

procedure TForm1.Son1Click(Sender: TObject);

var n, t: Integer;

begin

For n := 1 to 100 do begin

OutPort (97, (InPort (97) OR 2));

For t := 1 to 10000 Do;

OutPort (97, (InPort (97) AND 253));

For t := 1 to 10000 Do;

end;

end;

procedure TForm1.Son2Click(Sender: TObject);

var n: Integer;

begin

For n := 1 to 100 do begin

OutPort (97, (InPort (97) OR 2));

Delay (1);

OutPort (97, (InPort (97) AND 253));

Delay (1);

end;

end;

end.

Programme 1.5. Emission d’un son dans Delphi (Son1.pas).

Si la temporisation est réalisée par une boucle de comptage, la première chose que nous remarquons est la vitesse d’exécution, dix fois plus élevée dans l’ensemble qu’avec Visual Basic. Une boucle de comptage jusqu’à 10 000 sur un PC cadencé à 200 MHz nous donne une fréquence de quelque 5 kHz. Sur un ordinateur encore plus rapide, le son est à peine audible, tant sa fréquence est élevée.

Beaucoup d’applications sont affectées à des tâches dont le déroulement, fonction du temps, doit être indépendant de l’ordinateur sur lequel elles tournent. La procédure Delay permet en principe à un programme de se comporter de la même façon par rapport au temps, quel que soit l’environnement. Lorsque vous cliquez sur le bouton Son2, vous obtenez un son de 500 Hz, dont la programmation s’appuie sur Delay.

Il est également judicieux sous Delphi de rassembler toutes les déclarations de la DLL dans un module propre, qui prend ici la forme d’une unité. L’unité PORTINC.PAS (PORTINC.DCU, après compilation) peut alors être intégrée dans un autre projet, sans que le programmeur ait à s’occuper à nouveau des différentes conventions de déclaration.