De quoi parle-t’on ?
Du point de vu d’un processeur, les registres sont un espace de stockage particulier ; où des valeurs vitales pour l’exécution d’un programme sont enregistrées pour être exploitées de façon très rapide. En effet, les registres étant internes au processeur, il n’y a pas besoin de communiquer sur un bus relativement lent.
Les registres sont généralement réservés à la configuration et à l’exploitation des composants du microcontrôleur : les ports, les horloges, les interruptions, … Cet espace, bien que rapide, est de taille très limitée. Il n’est donc pas destiné à stocker des valeurs pour notre propre utilisation.
Ça va servir à quoi ?
L’ATtiny85 dispose de 64 registres de 8bits adressés de 0x00 à 0x3f . Dans ce document, vous trouverez à la page 7 la liste des registres du microcontrôleur, avec le nom de chaque bit.
On y trouve ainsi les registres PORTB, DDRB et PINB. Ces 3 registres seront les plus utilisés tout au long de ces tutoriels, car il s’agit des registres relatifs aux entrées et sorties du microcontrôleur.
Les registres d’entrées et sorties
Les entrées et sorties (Input/Output, souvent abrégé I/O) du microcontrôleur sont groupés par port. Pour l’ATtiny85, il n’y a qu’un seul port, le port B. Ainsi, la lettre B à la fin des noms des registres indique que ceux-ci sont destinés aux broches du port B.
DDRB : le registre «directions» du port B
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Nom | - | - | DDB5 | DDB4 | DDB3 | DDB2 | DDB1 | DDB0 |
Défaut | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Le registre DDRB indique les directions (entrée ou sortie) de chaque broche. Par défaut, les broches sont configurés en entrée (valeur 0). La valeur 1 correspond donc à une utilisation en sortie. Dans l’exemple ici, la ligne suivante configure la broche 0 du port B en sortie : DDRB = (1<<DDB0); .
PORTB : le registre «données» du port B
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Nom | - | - | PORTB5 | PORTB4 | PORTB3 | PORTB2 | PORTB1 | PORTB0 |
Défaut | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Une fois la direction définie, on peut attribuer la valeur souhaitée à la broche en utilisant ce registre. Par défaut, elle est desactivée ; pour l’activer on peut utiliser le code suivant PORTB |= (1<<PORTB0); .
PINB : le registre «entrée» du port B
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Nom | - | - | PINB5 | PINB4 | PINB3 | PINB2 | PINB1 | PINB0 |
Défaut | - | - | - | - | - | - | - | - |
Maintenant que l’on sait attribuer une valeur à la broche, voyons comment lire une valeur depuis le registre PINB. Imaginons un circuit connectant la broche PINB1 du microcontrôleur avec un bouton poussoir. Si celui-ci est pressé, alors je souhaite faire changer l’état de ma diode branchée sur PORTB0. Voici un exemple de code : if(PINB & (1<<PINB1)) PORTB ^= (1<<PORTB0);
Vous voici donc capable de jouer avec les broches de votre ATtiny ! Pour fêter celà, faites clignoter toutes les broches de votre microcontrôleur de cette façon : PORTB ^= 0x3F; .
Le registre d’interruption
Les interruptions sont un moyen de déclencher une action suite à un événement dans le microcontrôleur. Il peut s’agir d’un changement d’état d’une broche ou de l’épuisement d’une horloge (aussi appelé Timeout).
GIMSK : le registre général des interruptions
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Nom | - | INT0 | PCIE | - | - | - | - | - |
Défaut | - | 0 | 0 | - | - | - | - | - |
Ce registre configure le comportement des interruptions du microcontrôleur. Le bit INT0 est utilisé pour les interruptions externes, nous ne nous y intéresserons pas pour le moment. Le bit PCIE active le vecteur d’interruption sur les broches. Le registre suivant détaille son utilisation.
PCMSK : le registre des interruptions des broches
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Nom | - | - | PCINT5 | PCINT4 | PCINT3 | PCINT2 | PCINT1 | PCINT0 |
Défaut | - | - | 0 | 0 | 0 | 0 | 0 | 0 |
Reprenons l’exemple du bouton qui va changer l’état de la broche de la diode, voici un moyen de le faire avec des interruptions. Cette méthode a l’avantage d’être fonctionnelle dans n’importe quelle partie d’un programme plus complexe, puisqu’elle interrompra l’exécution courante.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <avr/io.h> #include <avr/interrupt.h> #define F_CPU 8000000L void main(void) { //On configure la broche 0 du port B en mode sortie. La broche 1 est en mode entrée par défaut. DDRB = (1<<DDB0); //On s'assure que la broche 0 est éteinte. PORTB &= ~(1<<DDB0); //On configure une interruption sur la broche 1. PCMSK = (1<<PCINT1); //On déclare l'activation des interruptions sur les changements d'état des broches GIMSK |= (1<<PCIE); //On active le support des interruptions sei(); } //On définit une macro qui s’exécutera dès qu'une broche aura changé d'état ISR(PCINT0_vect){ //On désactive les interruptions, afin de ne pas boucler cli(); //On vérifie que la broche active est bien la broche 1 if(PINB & (1<<PINB1)){ //On change l'état de la broche 0 PORTB ^= (1<<PORTB0); } //On réactive les interruptions sei(); } |
Pour la suite
J’espère vous avoir aidé à comprendre comment fonctionnent les registres de l’ATtiny85. La meilleure façon de travailler avec reste encore de garder la documentation à portée de main. En effet, tous les tableaux de ce chapitre sont issus de la documentation du microcontrôleur. Referez vous simplement à la page 7 du résumé de la documentation, qui indexe chaque registre.
Bonjour,
Merci pour cette introduction alléchante et francophone, ce qui est assez rare pour être souligné.
Tous mes encouragements pour la suite!!!
Michel
Merci pour ce blog,
un des meilleurs que j’ai pu trouvé en Francophone pour s’initier aux microcontrôleur.
J’espère qu’il y aura d’autres articles.