Entrées/sorties

GPIO

Introduction

Le terme GPIO signifie General Purpose Input/Output. Il désigne les broches sur lesquelles on peut prendre le contrôle manuellement.

Des exemples d'utilisation:

  • Allumer/éteindre une LED,
  • Vérifier l'état d'un bouton,
  • Activer un relais ou un transistor de puissance,
  • ...

Les GPIO dont nous parlons ici sont digitaux. Ils ne peuvent prendre que deux états: 0 ou 1.

Dans l'ATmega328P

Les broches de l'ATmega328P sont regrouppées par paquet de 8 (ce que l'on appelle un port). Chaque port est muni de 3 registres de configuration:

  • DDRx: Data Direction Register. Il permet de configurer les broches du port en entrée ou en sortie.
  • PORTx: Permet de configurer le niveau de la broche.
  • PINx: Il permet de lire l'état des broches du port.

Par exemple, pour allumer puis éteindre la LED branchée sur PB5:

// On configure PB5 en sortie
DDRB |= (1 << PB5);
// On met PB5 à 1
PORTB |= (1 << PB5);
// On attend 1 seconde
_delay_ms(1000);
// On met PB5 à 0
PORTB &= ~(1 << PB5);

GPIOs de l'ATmega328P, page 59 du datasheet.

Sortie à trois états

Lorsqu'elle est configurée en entrée, son voltage n'est pas déterminé, elle est dite "flottante" (floating), comme un fil qui ne serait branché à rien.

Une broche n'est donc pas simplement configurée à "0" ou à "1", mais aussi en "entrée" ou en "sortie". Lorsqu'elle est en entrée, on dit qu'ell est en haute impédance (parfois noté Hi-Z).

Par exemple, si on branche un bouton à une broche du microcontrôleur de cette façon:

Ou GND représente la masse du circuit, c'est à dire le 0V, on s'assure de lire "0" lorsque le bouton est appuyé. Mais que se passe t-il lorsqu'il est relâché? La broche est alors en haute impédance, et peut prendre n'importe quelle valeur.

Pour remédier à cela, on utilise des résistances de tirage (pull-up ou pull-down). Elles permettent de fixer le voltage de la broche lorsqu'elle est en haute impédance.

Avec ce montage, on s'assure de lire "1" lorsque le bouton est relâché.

Bonne nouvelle: les résistances de tirage sont intégrées à l'ATmega328P! Il suffit de les activer. Ce qui nous amène à un 4ème état, l'entrée avec pull-up. (Il n'existe pas d'entrée avec pull-down, mais cela est possible avec d'autres microcontrôleurs.)

On peut donc utiliser le code suivant pour regarder la valeur d'un bouton qui serait branché en PB4:

// On configure PB4 en entrée avec pull-up
DDRB &= ~(1 << PB4);
PORTB |= (1 << PB4);
// On lit la valeur de PB4
uint8_t btn = PINB & (1 << PB4);

Voici donc les états possible d'une broche:

DDRxPORTxEtat
10Sortie à 0
11Sortie à 1
00Entrée flottante
01Entrée pull-up

DAC

DAC signifie Digital to Analog Converter (convertisseur numérique vers analogique), il permet de convertir un nombre représenté en mémoire par des bits (par exemple de 0 à 1023) en une tension (par exemple de 0 à 5V).

PWM-DAC

Une solution simple pour réaliser cela est d'utiliser un signal périodique qui passe à travers un filtre passe-bas, produisant un signal "moyenné":

DAC Thermomètre

Une autre méthode est d'utiliser des résistances en série, permettant de représenter toutes les valeurs possibles. La sortie peut ensuite être sélectionnée à l'aide d'un multiplexeur. Cette solution a un encombrement important, car toutes les valeurs correspondent à un point physique dans le circuit.

R2R DAC

Enfin, la méthode R2R permet de combiner des résistances pour produire une tension directement à partir de la représentation binaire:

ADC

ADC est l'inverse de DAC, il permet de convertir une tension en un nombre représenté numériquement dans le programme.

Le design des ADC est dual à celui des DAC, en comparant les tensions produites avec l'entrée à échantillonner:

Par exemple, l'ADC "flash" (ci-dessus) est le dual du DAC thermomètre, contenant toutes les valeurs possibles de tension.

Dans l'ATmega328P, l'ADC est basé sur des comparaisons successives à l'aide de valeurs provenant d'un DAC interne:

Mesure de résistance

Un ADC permet de mesurer une tension (en V). On peut mesurer une résistance (en Ω) en utilisant un pont diviseur de tension:

La tension \(V_{out}\) sera alors:

\(V_{out} = V_{in} \times \frac{R_2}{R_1 + R_2}\)

Photorésistance

Une photorésistance varie sa résistance en fonction de la lumière qu'elle reçoit. Par exemple, cette référence varie de 20kΩ dans le noir à 8kΩ à pleine lumière:

⚙️ Exercice:

  • On alimente en 5V, et on utilise un ADC 0-5V. La photorésistance est placée (en bas) dans un pont diviseur de tension avec une résistance fixe. Pour chacune des valeurs possibles de cette dernière, déterminez la plage de mesure: 200Ω, 15kΩ, 100kΩ
  • Quelle résistance choisiriez vous?

Potentiomètre

Un potentiomètre est doté de 3 pattes:

Les pattes externes (vertes et bleues) sur la figure sont connectées à une résistance fixe. Une partie mobile ( en rouge sur la figure) peut être déplacée, changeant la résistance entre vert-rouge et rouge-bleu.

En appliquant une tension aux bornes du potentiomètre (broches vertes et bleues ci-dessus), on obtient une tension proportionnelle à la position de la partie mobile.