Prenons un exemple simple pour illustrer:
Nous travaillons avec un ATTINY1626.
https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ProductDocuments/DataSheets/ATtiny1624-26-27-DataSheet-DS40002234B.pdfVoir la tableau page 18 qui reprend les attributions de broches.
CAS: AND à 2 entrées:
Dans un code habituel nous ferions la lecture de 2 entrées et nous ferions l'association de leur état pour produire une sortie selon la combinaison en entrée
/*
* WE USE:
* PIN_PB0 PIN_PB1 as INPUT
* PIN_PB3 as OUTPUT
*/
#define ENTREE_1 PIN_PB0
#define ENTREE_2 PIN_PB1
#define SORTIE_1 PIN_PB3
void setup() {
// put your setup code here, to run once:
pinMode(ENTREE_1,INPUT);
pinMode(ENTREE_2,INPUT);
pinMode(SORTIE_1,OUTPUT);
}
void loop() {
bool IN1 = digitalRead(ENTREE_1);
bool IN2 = digitalRead(ENTREE_2);
bool OUT_STATE = IN1 & IN2;
digitalWrite(SORTIE_1,OUT_STATE);
}
Ce code est optimisable car les utilisations des fonctions digitalRead(), digitalWrite() sont gourmandes en temps.
Nous utiliserions pour cela de mode de manipulation direct des ports (et donc l'écriture dans les registres)
Explications ici par exemple:
https://github.com/SpenceKonde/DxCore/blob/master/megaavr/extras/DirectPortManipulation.mdOn utilise aussi 3 des 4 registres internes pouvant stoker chacun 1 byte.
Leur accès est ce qui est le plus rapide
Code optimisé:
#define SORTIE1_ON PORTB.OUTSET = PIN3_bm
#define SORTIE1_OFF PORTB.OUTCLR = PIN3_bm
#define IN1 GPIOR0
#define IN2 GPIOR1
#define OUT_STATE GPIOR3
void setup() {
// put your setup code here, to run once:
//PIN_PB0 AS INPUT:
PORTB.DIRSET = PIN0_bm;
//PIN_PB1 AS INPUT:
PORTB.DIRSET = PIN1_bm;
//PIN_PB3 AS OUTPUT
PORTB.DIRCLR = PIN3_bm;
}
void loop() {
// put your main code here, to run repeatedly:
IN1 = PORTB.IN & PIN0_bm;
IN2 = PORTB.IN & PIN1_bm;
OUTSTATE = IN1 & IN2;
if(OUTSTATE)
{
SORTIE1_ON;
}
else
{
SORTIE1_OFF;
}
}
En revanche nous avons perdu ici la "portabilité" du code d'un hardware vers un autre au bénéfice d'une performance accrue sur le hardware dédié.