L'intérêt de la manipulation des registres :
Registres de ports de l'ATMega328 :
PORTD registre de Port D des I/Os digital de D0 à D7 (PD0 à PD7)
DDRD : Registre de direction ("1" output et "0" input)
PORTD : Registre de données - écriture
PIND : Registre de donnée - lecture uniquement
PORTB registre de Port B des I/Os de D8 à D13 (PB0 à PB5, les PB6 et PB7 sont pas utilisables car elles sont réservé au quartz)
DDRB : Registre de direction ("1" output et "0" input)
PORTB : Registre de données - écriture
PINB : Registre de donnée - lecture uniquement
PORTC registre de Port C des I/Os de A0 à A5 (PC0 à PC5, les PC6 et PC7 sont pas utilisables)
DDRC : Registre de direction ("1" output et "0" input)
PORTC : Registre de données - écriture
PINC : Registre de donnée - lecture uniquement
Port B (broches numériques Arduino UNO D8 à D13) |
||||||||
Pins ATMega328 |
PB7 (MSB) |
PB6 |
PB5 |
PB4 |
PB3 |
PB2 |
PB1 |
PB0 (LSB) |
Pin Arduino |
- |
- |
D13 |
D12 |
D11 |
D10 |
D9 |
D8 |
N° du bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
PINB |
PINB7 |
PINB6 |
PINB5 |
PINB4 |
PINB3 |
PINB2 |
PINB1 |
PINB0 |
DDRB |
DDRB7 |
DDRB6 |
DDRB5 |
DDRB4 |
DDRB3 |
DDRB2 |
DDRB1 |
DDRB0 |
PORTD |
PORTD7 |
PORTD6 |
PORTD5 |
PORTD4 |
PORTD3 |
PORTD2 |
PORTD1 |
PORTD0 |
En gris c’est les bits de registres non utilisables du fait que les ports du même bit ne sont pas utilisés comme broche entrée/sortie.
Port C (broches analogique Arduino UNO A0 à A5) |
||||||||
Pins ATMega328 |
- |
PC6 (MSB) |
PC5 |
PC4 |
PC3 |
PC2 |
PC1 |
PC0 (LSB) |
Pin Arduino |
- |
- |
A5 |
A4 |
A3 |
A2 |
A1 |
A0 |
N° du bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
PINB |
PINC7 |
PINC6 |
PINC5 |
PINC4 |
PINC3 |
PINC2 |
PINC1 |
PINC0 |
DDRB |
DDRC7 |
DDRC6 |
DDRC5 |
DDRC4 |
DDRC3 |
DDRC2 |
DDRC1 |
DDRC0 |
PORTD |
PORTC7 |
PORTC6 |
PORTC5 |
PORTC4 |
PORTC3 |
PORTC2 |
PORTC1 |
PORTC0 |
Port D (broches numériques Arduino UNO D0 à D7) |
||||||||
Pins ATMega328 |
PD7 (MSB) |
PD6 |
PD5 |
PD4 |
PD3 |
PD2 |
PD1 |
PD0 (LSB) |
Pin Arduino |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
N° du bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
PINB |
PIND7 |
PIND6 |
PIND5 |
PIND4 |
PIND3 |
PIND2 |
PIND1 |
PIND0 |
DDRB |
DDRD7 |
DDRD6 |
DDRD5 |
DDRD4 |
DDRD3 |
DDRD2 |
DDRD1 |
DDRD0 |
PORTD |
PORTD7 |
PORTD6 |
PORTD5 |
PORTD4 |
PORTD3 |
PORTD2 |
PORTD1 |
PORTD0 |
Fonctionnement du circuit d'interface entre la partie numérique (code) et les pins I/O :
1. Écriture sur une pin :
Par exemple pour pouvoir allumer une LED sur la pin 4, donc mettre un état Haut sur cette broche, il faut d'abord commencer par mettre un “1” sur la bascule DDRD4 (1 correspond à sortie) puis mettre un “1” sur le registre PORTD4 c'est ce qu'on fait sur un programme Arduino habituel. Si on ne met pas un 1 d'abord sur DDRD4 avant d'en mettre sur PORTD4, le buffer lié à la sortie de PORTD sera pas activé donc restera ouvert, ce qui veut dire que l'état haut qu'on souhaite envoyer ne sera jamais acheminé jusqu'à la pin où est branché la LED qui veut dire qu'elle restera toujours éteinte. La lecture sur PIND4 doit relire un "1". Si on relit un "0" ça veut dire qu'il y a court-circuit !
2. Lecture d'une pin :
Par exemple pour la lecture de la broche D2 ça va être la même chose, il faut d'abord mettre un “0” (0 correspond à une entrée) au registre DDRD, ce qui va mettre en haute impédance le buffer et “débrancher” le registre PORTD de la pin. Reste plus qu’à lire le registre PIND.
Opérations logiques utilisé pour le langage bas niveau:
1. Opération de masquage :
- Isolation d'une donnée :
- Forçage à 1 (set) ou à 0 (reset) :
2. Opération de décalage :
Le décalage comme son nom l’indique est une opération qui consiste à décaler tous les chiffres d'un ou plusieurs crans vers la gauche (<<) ou la droite (>>). Les vides qui apparaissent après le décalage sont remplacés par des zéros.
Exemple :
1001100 >> 2 = 0010011 // on a décalé vers la droite de 2 crans
1001100 << 3 = 1100000 // on a décalé vers la gauche de 3 crans
3. Inversion de la valeur d'un bit :
On peut inverser la valeur d’un bit à l’aide de l’opération logique XOR (le symbole de XOR en C est ‘^’)
X ^ 1 = ! X
Rappe de la table de vérité de l’opération XOR :
X |
opération |
! X |
0 |
0 ^ 1 |
1 |
1 |
1 ^ 1 |
0 |
Exemple :
On souhaite inverser la valeur du 3 ième bit d’un mot de 8 bits : XXXXXXXX
Solution :
Mot=Mot ^ 0x08;
// on inverse le 3eme bit avec 0x08=1000
Comment coder le langage bas niveau ?
Maintenant qu’on a terminé sur la théorie indispensable pour la manipulation directe sur les registres, on peut commencer à voir des exemples avec des petits bouts de codes sur la façon de faire pour lire, écrire et configurer les broches de l’Arduino en entrée ou sortie avant de passer sur un code complet ou va faire ces 3 taches.
1.Configurer les ports de l'Arduino en entrée ou sortie :
Avant d’aller plus loin dans l’écriture
sur les ports, il faut faire attention sur les bits 0 et 1 des registres PORTx
(PORTB, PORTC et PORTD) de ne pas les modifier de leurs valeurs d’origine :
0BXXXXXX10.
Le bit ‘1’ correspond à Tx et le bit ‘0’ correspond à Rx, ces 2 broches servent de port à la communication série. Si par exemple, on modifie le bit 0 à ‘1’ alors la broche Rx deviens une sortie et donc elle ne peut plus recevoir de donnée alors que c’est sa tâche.
Dans le code suivant, on va travailler sur le port D (D0 à D7) où on va configurer les broches D5 et D2 en entrée et D4 et D7 en sortie.
Avant d’aller plus loin, on va rappeler dans un tableau tous les symboles utilisés dans les opérations logiques qu’on va utiliser dans ce cours :
Opération logiques |
Notation sur Arduino et C |
OR |
| |
AND |
& |
NOT |
! (pour un seul bit) |
NOT |
~ (pour tous les bits du mot) |
XOR |
^ |
Décalage à droite |
>> |
Décalage à gauche |
<< |
Etat logique haut |
1 |
Etat logique bas |
0 |
Pour la construction du programme, on commence par déclarer les broches :
#define pin5 5 //en entrée
#define pin6 6 //en entrée
#define pin4 4 //en sortie
#define pin7 7 //en sortie
Ensuite il faut mettre un ‘1’ sur les pins 4 et 7 pour les configurer en sortie et un ‘0’ sur les pins 5 et 6 pour les configurer en entrée sur le registre DDRD :
N° bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
DDRD |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
Ce qui donne le mot de 8 bits : 0B10010000 à mettre sur le registre DDRD
Ce mot peut se décomposer ainsi : 10010000=10000000 | 10000
On va nommer les ‘1’ pour la sortie en X et les ‘0’ pour l’entrée en Y pour mieux comprendre la construction du mot à inclure dans le code. Ce qui donne la décomposition suivante après avoir utilisé le décalage sur chaque des 4 bits :
X << 7 | Y << 6 | Y << 5 | X << 4 = X0000000 | Y000000 | Y00000 | X0000 = 10010000 =DDRD avec X=1 et Y=0
Cette ligne de code qui a le même rôle que la fonction pinMode() sera déposé dans la fonction setup() comme c’est habituel avec pinmode().
Code complet :
Programme en bas niveau réalisé |
Programme équivalent en fonctions Arduino |
#define pin5 5 //en entrée #define pin6 6 //en entrée #define pin4 4 //en sortie #define pin7 7 //en sortie
Void setup() { //on met les broches D4 et D7 en sortie //et les broches D5 et D6 en entrée DDRD = 1 << 7 | 0 <<6 | 0 << 5 | 1 << 4 ; } |
#define pin5 5 //en entrée #define pin6 6 //en entrée #define pin4 4 //en sortie #define pin7 7 //en sortie
Void setup() { pinMode( pin5, INPUT) ; pinMode( pin6, INPUT) ; pinMode( pin4, OUTPUT) ; pinMode( pin7, OUTPUT) ; } |
2. Écrire sur les ports de l'Arduino :
Dans cette partie on va essayer d’allumer 2 LEDs et de les éteindre après une seconde écoulé, l’une sur la broche D4 et l’autre sur la broche D7, évidemment toujours avec la manipulation des registres.
Pour commencer, on déclare les 2 broches utilisées :
#define led1 4
#define led2 7
Ensuite pour pouvoir allumer les 2 LEDs, on va mettre les broches D4 et D7 en sortie en mettant un ‘1’ sur le bit 4 et le bit 7 du registre de direction DDRD comme on la fait auparavant :
DDRD = 1 << 4 | 1 << 7 ;
Pour pouvoir allumer ces 2 LEDs il faudra envoyer +5v sur les 2 résistances qui sont lié aux 2 LEDs donc envoyer un état haut ‘1’ sur le registre de donnée PORTD du port D sur le bit 7 et le bit 4.
Pour ce faire, on écrit :
PORTD = PORTD | (1 << 4) | (1 << 7) ; //allumer la LED 1 et la LED 2
Explication :
Comme je l’ai cité avant, pour pouvoir forcer un bit à 1 il faut utiliser un masquage avec OR (|). C’est ce qui est fait ici, on applique un ‘1’ sur le bit 4 et le bit 7 sont pour autant changé les autres bits.
Le fait d’écrire directement PORTD = 0B10010000 directement fait pas très propre et risque de changer les autres bits.
Ensuite, pour pouvoir éteindre ces 2 LEDs après 1 seconde, il faut procéder de la même sorte que pour les allumer en envoyant un état bas ‘0’ sur les 2 bits 4 et 7 toujours avec le masquage mais cette fois avec l’opération AND (&) pour forcer les 2 bits à 0 :
delay(1000) ;
PORTD = PORTD & !(1<<4) & !(1<<7) ; //éteindre la LED 1 et la LED 2
Explication :
Cette ligne de code a le même fonctionnement que celle écrite pour allumer les LEDs sauf que cette fois on va forcer les 2 bits à 0 d’où l’utilisation de l’opération AND (&).
On a utilisé ‘ !1’ qui est la même chose que ī = 0. Ca fait plus propre qu’on utilisant des ‘0’ à la place des ‘1’ :
PORTD = PORTD & (0<<4) & (0<<7) ;
Code complet avec son équivalent en Arduino :
Programme en bas niveau réalisé |
Programme équivalent en fonction Arduino |
#define led1 4 #define led2 7
Void setup(){
DDRD = 1 << 4 | 1 << 7 ; }
Void loop(){ //on allume la led1 et la led2 PORTD = PORTD | (1 << 4) | (1 << 7) ; delay(1000) ; //on éteint la led1 et la led2 PORTD = PORTD & !(1<<4) & !(1<<7) ; }
|
#define led1 4 #define led2 7
Void setup(){ pinMode( pin4, OUTPUT) ; pinMode( pin7, OUTPUT) ; }
Void loop(){ //on allume la led1 et la led2 digitalWrite(led1, HIGH) ; digitalWrite(led2, HIGH) ; delay(1000) ; //on éteint la led1 et la led2 digitalWrite(led1, LOW) ; digitalWrite(led2, LOW) ; } |
3. Lecture sur les ports de l'Arduino :
Dans un premier temps, on va lire les broches D5 et D6 de l’Arduino sur lesquels sont branchés les boutons SW1 et SW2 respectivement. Les 2 boutons renvoient un état haut ‘1’ s'il est relâché (état initial) et un état bas ‘0’ s'il est appuyé. On va tester son état pour savoir s’il est appuyé ou pas.
Par la suite, on va faire un test sur le registre PIND pour savoir lequel des 2 boutons est appuyé. 4 cas sont possibles : aucun d’eux, seulement SW1 appuyé, seulement SW2 appuyé ou les 2 boutons appuyés.
Pour la déclaration des 2 broches en entrée sur la fonction setup(), on écrit :
#define SW1 5 //déclaration de la broche
#define SW2 6
Void setup(){
DDRD = !(1 << 4);// envoyer un ‘0’ (entrée) sur le bit N°4 su registre DDRD qui correspond à D4
Serial.begin(9600) ; //démarrage de la lecture série pour affichage du résultat sur le moniteur série
}
Pour le code dans la fonction loop(), pour la lecture et les tests on va travailler avec une variable de 8 bits (byte) qui va accueillir la valeur du registre PIND.
On va commencer par lire le contenue du registre PIND :
byte etat_SW ;
etat_SW=PIND ;
Serial.prinntln(etat_SW) ;
Résultat sur les valeurs possibles qui seront retournés par le registre PIND :
- Si aucun bouton est appuyé DDRD=0
- Si seulement le bouton SW2 est appuyé DDRD=1000000=0x40
- Si seulement le bouton SW1 est appuyé DDRD=100000=0x20
- Si les 2 boutons SW1 et SW2 sont appuyés DDRD=1100000=0x60
Pour les 4 tests, on va faire simple, on va tester si la variable etat_SW est égal à l’une de ces 4 valeurs vue précédemment pour identifier quel bouton est appuyé.
if(etat_SW ==0) Serial.println(‘’ aucun boutton n’est appuyé’’) ;
else if(etat_SW==0x40) Serial.println(‘’ seulement le bouton SW2 est appuyé’’) ;
else if(etat_SW==0x20) Serial.println(‘’ seulement le bouton SW1 est appuyé’’) ;
else if(etat_SW==0x60) Serial.println(‘’ les 2 boutons SW1 et SW2 sont appuyés’’) ;
Code complet :
Cas spécial :
Si on souhaite lire uniquement le bit N°5, on a le choix entre 2 options :
Option 1 : en utilisant le masquage puis le décalage sur la variable etat_SW.
Le bit à masquer est sur le bit N°5 ce qui donne à la valeur du masque 0B100000(BIN) = 0x10(HEX) après avoir effectué le masquage on va le décaler vers la droite de 5 bits :
byte etat_SW ;
etat_SW = (PIND & 0x20) >> 5 ;
Option 2 : déclarer etat_SW en un type de variable à 1 bit (boolean sur Arduino) et utiliser un masquage sans décalage sur PIND puisque la variable n’a qu’un seul bit !
boolean etat_SW ;
etat_SW=DDRD & 0x20 ;
4. Activation de résistances pull-up de l’ATMega
Aperçu de circuit à base résistance pull-up et pull-down.
Une résistance pull up (en français la résistance de tirage) permet de fixer une entrée numérique à un état haut (+5v) ou bas (0v). Elle permet aussi d'éliminer les broches flottantes et surtout, d'établir deux états électriques distincts:
- - un état haut (HIGH);
- - un état bas (LOW).
Il y a 2 sortes de résistances de tirage :
- - Résistance ‘’pull-up’’, tirage vers le HAUT
- - Résistance ‘’pull-down’’, tirage vers le BAS
Sur l’ATMega328, toutes les broches numériques (Dx) disposent des résistances pull-up internes configurables. On peut les activer ou pas numériquement via les registres de donnée PORTx.
Habituellement on utilise un bouton avec une résistance pull-up externe pour pouvoir l’utiliser. Il est possible de s’en passer en utilisant les résistances pull-up internes avec la fonction Arduino pinMode() comme ceci :
pinMode(Num_broche, INPUT_PULLUP);//activation de la résistance pull-up interne sur Num_broche et configuration de cette dernière en entrée
Afin d'activer les pull-up interne du microcontrôleur en manipulent les registres, il suffit juste d’écrire 2 lignes de code. Cela revient à mettre cette pin en entrée (DDRx=0) et mettre un ‘1’ sur PORTx où on veut activer la résistance pull up :
DDRx=0 et PORTx=1
Pour désactiver la résistance Pull Up de la énième broches, on fait exactement l'inverse :
DDRx.n=1 et
PORTx=0
Exemple :
On souhaite mettre la broche D1 en entrée avec pull up interne (sur le port D) :
DDRD=DDRD & ~0x02 //DDRD.1 <- 0 PORTD=PORTD | 0x02 //PORTD.1 <- 1 |
Détail : le bit PUD du registre MCUCR permet la désactivation de toutes les résistances de pull-up.
Si on met PUD=1 alors toutes les résistances de pull-up interne de tous les ports seront désactivées.
Exemples de programmes complets en langage bas niveau :
Maintenant qu’on a vue toute les manipulations sur les registres nécessaires pour la configuration des broches numérique et analogique de l’Arduino (pour les versions Uno et Nano qui sont équipé de l’ATMega328), on va voir quelques exemples de programmes complets sur lesquels on va utiliser toutes les opérations vue précédemment.
1. Code Blink de l’IDE d’Arduino :
Le fameux simple code que tout le monde à utiliser pour faire clignoter la LED “L” présente sur la broche 13 de l’Arduino UNO :)
Dans ce qui va suivre, on va réécrire le code blink avec un langage bas niveau c’est à dire sans fonction Arduino :
#define led13 5 // la pin 13 est sur le 5 ième bit du port B // Version langage bas niveau du programme Blink de Arduino void setup() { DDRB=1<<led13; //configuration de la pin 13 en sortie }
void loop() { PORTB=PORTB | 0x20; // on met un 1 sur le 5 ième bit du du registre PORTB pour allumer la LED delay(1000); PORTB = PORTB & ~0x20; // on met un 0 sur le 5 ième bit du du registre PORTB pour éteindre la LED delay(1000); /* //ou tout simplement avec un XOR qui va inverser la valeur du bit à chaque itération de la fonction loop(): PORTB =PORTB ^ 0x20; delay(1000); */ } |
2. Commande de 2 LEDs à partir de 2 boutons :
Dans cet application on va commander 2 LEDs à partir de 2 boutons :
- - Le bouton SW1 avec la résistance R3 en pull-down
- - Le bouton SW2 avec la résistance R4 en pull-up
Le circuit de notre application.
Cahier des charges :
Construire un code qui va allumer les LEDs selon le/les boutons appuyés sur les 2 circuits :
- Allumer la LED1 si le bouton SW1 est appuyé
- Allumer la LED2 si le bouton SW2 est appuyé
- Allumer les 2 LEDs si les 2 boutons sont appuyés
- Ne rien faire si aucun des boutons n’est appuyé.
On commence par l’étude du circuit :
A l’état initial (avant qu’un bouton soit appuyé),
- - le bouton SW1 retourne un état bas ‘0’
- - le bouton SW2 retourne un état haut ‘1’
A l’appui,
- - le bouton SW1 retourne un état haut ‘1’
- - le bouton SW2 retourne un état bas ‘0’
Pour les LEDs, il suffit d’envoyer
- - un état haut ‘1’ sur les allumer
- - un état bas pour les éteindre
Avec cette étude, on peut maintenant tracer la table de vérité de ce circuit :
- - pour les boutons (SW1 et SW2) ‘1’ : relâché et ‘0’ : appuyé
- - pour les LEDs (LED1 et LED2) ‘0’ : éteint et ‘1’ allumé
Pour allumer la LED1, il faut appuyer sur le
SW1 |
SW2 |
LED1 |
LED2 |
0 relâché |
1 relâché |
0 |
0 |
0 relâché |
0 appuyé |
0 |
1 |
1 appuyé |
1 relâché |
1 |
0 |
1 appuyé |
0 appuyé |
1 |
1 |
A partir cette table de vérité on peut voir que :
- - l’état de SW1 et LED1 sont est égal : SW1 = LED1
- - l’état de SW2 et LED2 sont inverse : SW2 = ~ LED2
Les broches utilisées dans cette application sont comprises entre D0 et D7 de l’Arduino ce qui veut dire que le port utilisé est le port D donc tout les registres qu’on va manipulé sont aussi de ce port.
Les bits N° 5 et 6 seront utilisés pour la lecture des 2 boutons à travers le registre PIND.
Les bits N° 4 et 7 seront utilisés pour l’écriture sur les leds à travers le registre PORTD.
Sur le registre PIND, on peut considérer les bits non utilisé étants nuls :
0 |
D6 (SW2) |
D5 (SW1) |
0 |
0 |
0 |
0 |
0 |
PIND |
Même chose sur le registre PORTD, on envoie des ‘0’ pour les bits non utilisés :
D7 (LED2) |
0 |
0 |
D4 (LED1) |
0 |
0 |
0 |
0 |
PORTD |
Afin d’avoir un code simple mais surtout compacte on va directement placer le bit PIND5 (D5) dans PORTD4 (D4) et l’inverse du bit PIND6 (D6) dans PORTD7 (D7) comme on l’a vu sur la table de vérité.
Comment faire ?
D’abord pour isoler les bits PIND5 et PIND6 du registre PIND de 8 bits, on va utiliser le masquage AND (&) :
PIND5=PIND & 0B00100000=PIND & 0x20
PIND6=PIND & 0B01000000=PIND & 0x40
Comme on l’a vu précédemment :
LED1=SW1 et LED2= ~SW2
↔ PIND5= PIND5 et PIND6= ~PIND6 (l’opérateur ‘~’ est utilisé pour inverser)
L’inversion faite reste plus qu’à déplacer les bits comme détaillé précédemment à l’aide de l’opérateur de décalage. Il faut déplacer PIND6 sur PORTD7 d'une position (décalage à gauche avec <<1 ) et PIND5 sur PORTD4 d’une position aussi (décalage à droite avec >>1) ce qui donne :
PORTD7=PIND6 << 1 et
PORTD4=PIND5 >>1
Reste plus qu’à assembler tout ça on sommant (avec | ) les 2 parties, PORTD4 et PORTD7. Ce qui donne :
PORTD=((~PIND&0x40)<<1)|((PIND&0x20)>>1 |
NB : Cette relation est celle et la seule qu’on va mettre dans la fonction loop() !
Pour la fonction setup() :
Configuration des ports à travers le registre DDRD :
DDRD= 0<<bouton1 | 0<<bouton2 | 1<<led1 | 1<<led2;
Cette ligne est équivalent à : 0<<5 | 0<<6 | 1<<led4 | 1<<led7;
Le code complet :
Programme en bas niveau réalisé |
Programme équivalent en fonctions Arduino |
#define bouton1 5 #define bouton2 6 #define led1 4 #define led2 7
void setup(){ Serial.begin(9600); DDRD= 0<<bouton1 | 0<<bouton2 | 1<<led1 | 1<<led2; //DDRD=0B10010000; }
void loop(){ PORTD=((PIND&0x40)<<1)|((~PIND&0x20)>>1); }
|
#define bouton1 5 #define bouton2 6 #define led1 4 #define led2 7
boolean etat1,etat2; void setup() { Serial.begin(9600); pinMode(bouton1,INPUT); pinMode(bouton2,INPUT); pinMode(led1,OUTPUT); pinMode(led2,OUTPUT); } void loop() { etat1=digitalRead(bouton1); etat2=digitalRead(bouton2); digitalWrite(led1, bouton1); digitalWrite(led2, !bouton2); } |
Conclusion :
Dans cet article on a vu différente opération sur les ports numériques et analogiques qu’on peut mener sur le microcontrôleur ATMega328, ce qui nous donne la possibilité de le programmer en langage bas niveau qui rend le code plus compacte et rapide et on peut même programmer Arduino en langage C.
Après pour faire ça, il faut bien faire attention car cette méthode présente quelques inconvénients :
- - Le code sera moins visible donc plus difficile à vérifier ou modifier.
- - La portabilité vers d’autres cartes sera moins évidente.
- - Il pourrait y avoir des dysfonctionnement si on ne manipule pas les bons registres.
Source :
Arduino.cc
https://fr.wikiversity.org/wiki/Micro_contr%C3%B4leurs_AVR/Les_PORTs
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdfSource
Aucun commentaire:
Enregistrer un commentaire