Rédacteur : Philippe Mariano
[Mise à jour le 8/4/2020]
« Dans un système à base de microcontrôleur, on appelle entrées-sorties les échanges d'informations entre le processeur et les périphériques qui lui sont associés. De la sorte, le système peut réagir à des modifications de son environnement, voire le contrôler. Elles sont parfois désignées par l'acronyme I/O, issu de l'anglais Input/Output ou encore E/S pour entrées/sorties. » Wikipédia
Pour éviter de faire référence à des valeurs électriques (tension ou intensité), on définit souvent l’état d’un signal numérique en utilisant la logique booléenne.
- true (« 1 » logique) correspondra par exemple à 5V ou 3,3V
- false (« 0 » logique) correspondra à 0V.
Un microcontrôleur dispose de broches pouvant être contrôlées par un logiciel. Elles peuvent se comporter comme des entrées ou des sorties, d'où le nom “entrée / sortie à usage général”, ou GPIO (General Purpose Input Output.
Le nombre de broches d’un microcontrôleur étant limité, il est fréquent d’avoir plusieurs fonctionnalités sur une même broche.
Les connexions D13 à D0 peuvent être configurées en entrée ou en sortie numérique. On voit sur la copie d’écran ci-dessous qu’elles partagent la connectique avec d’autres fonctionnalités (PWM, SPI etc.).
Un programme implanté dans une carte FEZ accède à ses entrées, sorties numériques par l’intermédiaire des bibliothèques (assemblys)
suivantes :
- GHIElectronics.TinyCLR.Devices.Gpio (les entrées, sorties)
- GHIElectronics.TinyCLR.Pins (les définitions des broches)
Ces bibliothèques sont installées dans le projet sous la forme de paquets NuGet comme dans l'exemple ci-contre.
L'installation de ces bibliothèques est détaillée dans :
L'accès aux entrées, sorties s'écrira plus simplement en entrant les espaces de noms suivants dans le programme.
using GHIElectronics.TinyCLR.Pins; using GHIElectronics.TinyCLR.Devices.Gpio;
Les entrées numériques permettent de détecter un état logique « 0 » ou « 1 ».
Les entrées numériques sont fragiles. Elles ne supportent ni les décharges électrostatiques ni les surtensions. Il ne faut ni les toucher ni leur appliquer une tension supérieure à 5V ou inférieure à 0V.
Une entrée numérique utilisée dans un programme ne doit pas être laissée “en l’air” (non connectée) car elle prendra alors un état logique aléatoirement et le comportement du programme deviendra imprévisible.
Remarque : le processeur de la carte FEZ dispose de résistances de rappel internes pouvant être connectées par le logiciel.
L’accès à une entrée numérique “physique” se fait à l'aide d’un objet logiciel GPIOpin. Pour cela, il faut :
Les différentes configurations possibles pour une broche sont énumérées dans GpioPinDriveMode.
Exemple : configuration de la broche connectée au bouton-poussoir BTN1 de la carte FEZ.
// 1. Création de l'objet gpio (classe GpioController) auquel on affecte le // contrôleur GPIO de la carte ciblée (à déclarer une seule fois). var gpio = GpioController.GetDefault(); // 2. Création de l'objet btn1 (classe GpioPin) auquel on affecte // la broche associée au bouton-poussoir BTN1, // broche ouverte par OpenPin, var btn1 = gpio.OpenPin(FEZ.GpioPin.Btn1); // 3. Configuration de la broche reliée à BTN1 en entrée avec // une résistance de rappel btn1.SetDriveMode(GpioPinDriveMode.InputPullUp);
La lecture d'une entrée numérique se fait avec une méthode Read() de la classe GpioPin.
Exemple : Le bouton-poussoir BTN1 est utilisé pour commander la led LED1 de la carte FEZ.
if (btn1.Read()== GpioPinValue.High) { LED1.Write(GpioPinValue.Low); } else { LED1.Write(GpioPinValue.High); }
Une sortie numériqque est fragile. Ne JAMAIS la relier à un générateur
Une sortie numérique délivre très peu de puissance (quelques centaines de mW). Il n’est donc pas possible de la relier directement à un actionneur (moteur). Il est nécessaire de placer une interface de puissance (hacheur, relais) entre elle et l’actionneur à commander.
L’accès à une sortie numérique “physique” se fait à l'aide d’un objet logiciel GPIOpin. Pour cela, il faut :
Les différentes configurations possibles pour une broche sont énumérées dans GpioPinDriveMode.
Exemple : configuration de la broche connectée à la LED1 de la carte FEZ.
// 1. Création de l'objet gpio (classe GpioController) auquel on affecte le // contrôleur GPIO de la carte ciblée (à déclarer une seule fois). var gpio = GpioController.GetDefault(); // 2. Création de l'objet led1 (classe GpioPin) auquel on affecte // la broche associée à LED1. // broche ouverte par OpenPin, var btn1 = gpio.OpenPin(FEZ.GpioPin.LED1); // 3. Configuration de la broche reliée à LED1 en sortie. btn1.SetDriveMode(GpioPinDriveMode.OutPut);
Une sortie numérique peut prendre l’état true ou false. Cet état est contrôlé avec la méthode Write.
Exemple : Le bouton-poussoir BTN1 est utilisé pour commander la led LED1 de la carte FEZ.
if (btn1.Read()== GpioPinValue.High) { LED1.Write(GpioPinValue.Low); } else { LED1.Write(GpioPinValue.High); }
using GHIElectronics.TinyCLR.Devices.Gpio; using GHIElectronics.TinyCLR.Pins; using System.Threading; namespace TCLR_FEZ_LED1_Btn1 { class Program { static void Main() { var gpio = GpioController.GetDefault(); var LED1 = gpio.OpenPin(FEZ.GpioPin.Led1); LED1.SetDriveMode(GpioPinDriveMode.Output); var btn1 = gpio.OpenPin(FEZ.GpioPin.Btn1); btn1.SetDriveMode(GpioPinDriveMode.InputPullUp); while (true) { if (btn1.Read() == GpioPinValue.High) { LED1.Write(GpioPinValue.Low); } else { LED1.Write(GpioPinValue.High); } Thread.Sleep(10); } } } }
Une interruption est un arrêt temporaire de l'exécution normale d'un programme par le processeur afin d'exécuter un autre programme (appelé service d'interruption).
L’interruption est provoquée par une cause externe (action sur un bouton-poussoir, mesure réalisée par un capteur, horloge temps réel, etc.).
On utilise les interruptions afin de permettre des communications non bloquantes avec des périphériques externes.
Une interruption tient compte de l’état logique présent sur une broche. Couramment, on la déclenchera sur le front montant, le front descendant, ou chacun des fronts d’un signal logique.
Une interruption sera reconnue si le signal présente des fronts “propres”. Il faudra donc s’assurer de la qualité du signal. Les figures ci-dessous représentent un signal transmis à la fermeture du contact d’un anémomètre. Le signal de gauche n’est pas utilisable, car, à cause du rebondissement du contact, il contient quatre fronts montants au lieu d’un seul comme dans le cas du signal de droite.
La configuration en entrée de la broche destinée à recevoir un évènement est identique à celle du paragraphe 4.
Un évènement est attaché à un gestionnaire (service d'interruption) comme dans l'exemple suivant où le Btn1 commande la LED1 de la carte FEZ lorsqu'un front montant apparaît sur la broche.
using GHIElectronics.TinyCLR.Devices.Gpio; using GHIElectronics.TinyCLR.Pins; using System.Threading; namespace TCLR_FEZ_LED1_Btn1_INT { class Program { private static GpioPin LED1; private static void Main() { var gpio = GpioController.GetDefault(); LED1 = gpio.OpenPin(FEZ.GpioPin.Led1); LED1.SetDriveMode(GpioPinDriveMode.Output); var btn1 = gpio.OpenPin(FEZ.GpioPin.Btn1); btn1.SetDriveMode(GpioPinDriveMode.InputPullUp); // Prise en compte de l'interruption btn1.ValueChanged += Btn1_ValueChanged; Thread.Sleep(-1); // Mise en Veille pour réduire la consommation // d'énergie et permettre au système d'effectuer d'autres tâches. } private static void Btn1_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e) { if (e.Edge == GpioPinEdge.RisingEdge) LED1.Write(GpioPinValue.Low); else LED1.Write(GpioPinValue.High); } } }