Différences entre versions de « Atmega328 registers »
Ligne 32 : | Ligne 32 : | ||
|} | |} | ||
− | = Manipulations = | + | == Manipulations == |
− | Maintenant que l'on à | + | Maintenant que l'on à identifié le groupe et la position du bit des broches dans les registres, nous pouvons passer à la manipulation ! |
− | |||
− | |||
− | == | + | Reprenons l'exemple de la broche D13. Pour modifier sont état, il suffit de modifier la valeur de PORTB: |
+ | <source lang="c"> | ||
+ | PORTB = B00100000; // pour mettre D13 à HIGH | ||
+ | PORTB = B00000000; // pour mettre D13 à LOW | ||
+ | </source> | ||
+ | Seulement voila, on sait que sa position dans les registres correspond au bit numéro 6 mais on a absolument aucune idée de la valeur de PORTB au moment de la modification ! | ||
+ | La manipulation précédente va certainement modifier l'état de D13 mais va aussi modifier l'état des autre broches du groupe '''B'''. On ne peut donc pas agir de la sorte, il faut utiliser un opérateur logique pour modifier les registres et on va distinguer deux cas de figures: le passage à ''1'' et celui à ''0''. | ||
− | == Passage d' | + | == Passage à ''1'' == |
+ | {| | ||
+ | |- | ||
+ | |valign="top" width="40%"| | ||
+ | Pour modifier l'état d'un registre à ''1'' sans modifier l'état des autres registres nous allons utiliser l'opérateur ''OU''. | ||
+ | |||
+ | Si on reprend l'exemple précédent, nous allons plutôt faire cela: | ||
+ | <source lang="c"> | ||
+ | PORTB |= B00100000; // pour mettre seulement D13 à HIGH | ||
+ | </source> | ||
+ | Imaginons que PORTB est la valeur suivante ''B00010101'', PORTB |= B00100000 revient à faire: | ||
+ | {|align="center" | ||
+ | |- | ||
+ | ||||0||0||0||1||0||1||0||1 | ||
+ | |- | ||
+ | ||ou||0||0||1||0||0||0||0||0 | ||
+ | |- | ||
+ | |colspan="9"|<hr> | ||
+ | |- | ||
+ | ||||0||0||1||1||0||1||0||1 | ||
+ | |} | ||
+ | On a donc réussi à modifier la valeur de D13 sans modifier l'état des autres broches ! | ||
+ | |width="1%"| | ||
+ | |width="12%" valign="top"| | ||
+ | Table de vérité de OU | ||
+ | {|border="1" | ||
+ | |- | ||
+ | |width="60px" align="center"| | ||
+ | A | ||
+ | |width="60px" align="center"| | ||
+ | B | ||
+ | |width="60px" align="center"| | ||
+ | A OU B | ||
+ | |- | ||
+ | |align="center"| | ||
+ | 0 | ||
+ | |align="center"| | ||
+ | 0 | ||
+ | |align="center"| | ||
+ | 0 | ||
+ | |- | ||
+ | |align="center"| | ||
+ | 0 | ||
+ | |align="center"| | ||
+ | 1 | ||
+ | |align="center"| | ||
+ | 1 | ||
+ | |- | ||
+ | |align="center"| | ||
+ | 1 | ||
+ | |align="center"| | ||
+ | 0 | ||
+ | |align="center"| | ||
+ | 1 | ||
+ | |- | ||
+ | |align="center"| | ||
+ | 1 | ||
+ | |align="center"| | ||
+ | 1 | ||
+ | |align="center"| | ||
+ | 1 | ||
+ | |} | ||
+ | |width="1%"| | ||
+ | |valign="top" width="40%"| | ||
+ | On peut également effectuer cette manipulation par décalage de bit. Dans l'exemple précédent nous avons utilisé ''B00100000'' pour faire le OU mais on aurait pu utiliser l'écriture ''(1<<5)''. | ||
+ | Le chiffre ''1'' est un entier qui s'écrit en binaire comme cela: | ||
+ | {|align="center" | ||
+ | |- | ||
+ | ||position||7||6||5||4||3||2||1||0 | ||
+ | |- | ||
+ | ||valeur||0||0||0||0||0||0||0||1 | ||
+ | |} | ||
+ | Il nous suffit donc de le décaler de 5 position vers la gauche pour obtenir B00100000: | ||
+ | {|align="center" | ||
+ | |- | ||
+ | ||position||7||6||5||4||3||2||1||0 | ||
+ | |- | ||
+ | ||valeur||0||0||1||0||0||0||0||0 | ||
+ | |} | ||
+ | Les deux écritures suivantes sont donc équivalentes: | ||
+ | <source lang="c"> | ||
+ | PORTB |= B00100000; | ||
+ | PORTB |= (1<<5); | ||
+ | </source> | ||
+ | |} | ||
+ | == Passage à ''0'' == | ||
+ | {| | ||
+ | |- | ||
+ | |valign="top" width="40%"| | ||
+ | Pour modifier l'état d'un registre à ''1'' sans modifier l'état des autres registres nous allons utiliser l'opérateur ''ET''. | ||
+ | |||
+ | Si on reprend l'exemple précédent, nous allons plutôt faire cela: | ||
+ | <source lang="c"> | ||
+ | PORTB &= ~B00100000; // pour mettre seulement D13 à LOW | ||
+ | </source> | ||
+ | L'opérateur ''~'' permet d'obtenir le [https://fr.wikipedia.org/wiki/Compl%C3%A9ment_%C3%A0_un complément A1] d'un nombre binaire: B00100000 devient alors B11011111. | ||
+ | |||
+ | Imaginons que PORTB est la valeur suivante ''B00010101'', PORTB &= ~B00100000 revient à faire: | ||
+ | {|align="center" | ||
+ | |- | ||
+ | ||||0||0||0||1||0||1||0||1 | ||
+ | |- | ||
+ | ||ET||1||1||0||1||1||1||1||1 | ||
+ | |- | ||
+ | |colspan="9"|<hr> | ||
+ | |- | ||
+ | ||||0||0||0||1||0||1||0||1 | ||
+ | |} | ||
+ | On a donc réussi à modifier la valeur de D13 sans modifier l'état des autres broches ! | ||
+ | |width="1%"| | ||
+ | |width="12%" valign="top"| | ||
+ | Table de vérité de ET | ||
+ | {|border="1" | ||
+ | |- | ||
+ | |width="60px" align="center"| | ||
+ | A | ||
+ | |width="60px" align="center"| | ||
+ | B | ||
+ | |width="60px" align="center"| | ||
+ | A ET B | ||
+ | |- | ||
+ | |align="center"| | ||
+ | 0 | ||
+ | |align="center"| | ||
+ | 0 | ||
+ | |align="center"| | ||
+ | 0 | ||
+ | |- | ||
+ | |align="center"| | ||
+ | 0 | ||
+ | |align="center"| | ||
+ | 1 | ||
+ | |align="center"| | ||
+ | 0 | ||
+ | |- | ||
+ | |align="center"| | ||
+ | 1 | ||
+ | |align="center"| | ||
+ | 0 | ||
+ | |align="center"| | ||
+ | 0 | ||
+ | |- | ||
+ | |align="center"| | ||
+ | 1 | ||
+ | |align="center"| | ||
+ | 1 | ||
+ | |align="center"| | ||
+ | 1 | ||
+ | |} | ||
+ | |width="1%"| | ||
+ | |valign="top" width="40%"| | ||
+ | On peut également effectuer cette manipulation par décalage de bit. Dans l'exemple précédent nous avons utilisé ''~B00100000'' pour faire le OU mais on aurait pu utiliser l'écriture ''~(1<<5)''. | ||
+ | Les deux écritures suivantes sont donc équivalentes: | ||
+ | <source lang="c"> | ||
+ | PORTB &= ~B00100000; | ||
+ | PORTB &= ~(1<<5); | ||
+ | </source> | ||
+ | |} |
Version du 1 novembre 2018 à 16:32
Introduction
Lorsque l'on commence à écrire des programmes qui sortent de l'ordinaire ou que l'on veut pousser un microcontrôleur à la limite de ces capacité, il est obligatoire de descendre au niveau des registres. Seulement voila, la manipulation de registre ne s'improvise pas, nécessite de connaître le hardware que l'on utilise et, de par sa nature, est spécifique à un type de microcontrôleur !
Manipuler les registre implique donc de sacrifier la portabilité du code, offerte par l'utilisation des fonctions haut niveau comme digitalWrite(), au profit de la vitesse d'exécution et de la compacité du code.
Les fonctions comme digitalWrite(), digitalRead(), pinMode() permettent au développeur d'accomplir une action sans avoir à se soucier du type de microcontrôleur utilisé mais, in finé, elle vont elle même manipuler les registres pour accomplir ces tâches !
Le cas de l'ATmega328
Manipulations
Maintenant que l'on à identifié le groupe et la position du bit des broches dans les registres, nous pouvons passer à la manipulation !
Reprenons l'exemple de la broche D13. Pour modifier sont état, il suffit de modifier la valeur de PORTB:
PORTB = B00100000; // pour mettre D13 à HIGH
PORTB = B00000000; // pour mettre D13 à LOW
Seulement voila, on sait que sa position dans les registres correspond au bit numéro 6 mais on a absolument aucune idée de la valeur de PORTB au moment de la modification ! La manipulation précédente va certainement modifier l'état de D13 mais va aussi modifier l'état des autre broches du groupe B. On ne peut donc pas agir de la sorte, il faut utiliser un opérateur logique pour modifier les registres et on va distinguer deux cas de figures: le passage à 1 et celui à 0.
Passage à 1
Pour modifier l'état d'un registre à 1 sans modifier l'état des autres registres nous allons utiliser l'opérateur OU. Si on reprend l'exemple précédent, nous allons plutôt faire cela: PORTB |= B00100000; // pour mettre seulement D13 à HIGH
Imaginons que PORTB est la valeur suivante B00010101, PORTB |= B00100000 revient à faire:
On a donc réussi à modifier la valeur de D13 sans modifier l'état des autres broches ! |
Table de vérité de OU
|
On peut également effectuer cette manipulation par décalage de bit. Dans l'exemple précédent nous avons utilisé B00100000 pour faire le OU mais on aurait pu utiliser l'écriture (1<<5). Le chiffre 1 est un entier qui s'écrit en binaire comme cela:
Il nous suffit donc de le décaler de 5 position vers la gauche pour obtenir B00100000:
Les deux écritures suivantes sont donc équivalentes: PORTB |= B00100000;
PORTB |= (1<<5);
|
Passage à 0
Pour modifier l'état d'un registre à 1 sans modifier l'état des autres registres nous allons utiliser l'opérateur ET. Si on reprend l'exemple précédent, nous allons plutôt faire cela: PORTB &= ~B00100000; // pour mettre seulement D13 à LOW
L'opérateur ~ permet d'obtenir le complément A1 d'un nombre binaire: B00100000 devient alors B11011111. Imaginons que PORTB est la valeur suivante B00010101, PORTB &= ~B00100000 revient à faire:
On a donc réussi à modifier la valeur de D13 sans modifier l'état des autres broches ! |
Table de vérité de ET
|
On peut également effectuer cette manipulation par décalage de bit. Dans l'exemple précédent nous avons utilisé ~B00100000 pour faire le OU mais on aurait pu utiliser l'écriture ~(1<<5). Les deux écritures suivantes sont donc équivalentes: PORTB &= ~B00100000;
PORTB &= ~(1<<5);
|