A chacun d'apprécier...
Pour rester dans le sujet, j'ai fait un petit code qui écrit et lit sur un port parallèle 4 bits + R/W + CLK. tout simple.
boucle :
mode Write;
présenter les données sur le port data;
faire un pulse sur CLK;
mode Read;
faire un pulse sur CLK;
récupérer les données sur le port data;
Le code en passant par des pinMode() et digitalWrite()/Read() :
void setup() {
pinMode (8, OUTPUT); // R/W : PB0
pinMode (9, OUTPUT); // clock : PB1
}
byte dumyIn; // variable de lecture
byte dumyOut; // variable d'écriture
void loop() {
// -----------------Write data---------
pinMode (2, OUTPUT); // data 0 : PD2
pinMode (3, OUTPUT); // data 1 : PD3
pinMode (4, OUTPUT); // data 2 : PD4
pinMode (5, OUTPUT); // data 3 : PD5
digitalWrite (9, LOW); // Write data
digitalWrite (2, (dumyOut & 0x01)); // set data
digitalWrite (3, (dumyOut & 0x02) >> 1);
digitalWrite (4, (dumyOut & 0x04) >> 2);
digitalWrite (5, (dumyOut & 0x08) >> 3);
digitalWrite (8, HIGH); // clock rising
delay(2);
digitalWrite (8, LOW); // clock falling
// -----------------Read data---------
pinMode (2, INPUT);
pinMode (3, INPUT);
pinMode (4, INPUT);
pinMode (5, INPUT);
digitalWrite (9, HIGH);
digitalWrite (8, HIGH); // clock rising
delay(2);
dumyIn = digitalRead (2); // read data
dumyIn |= digitalRead (3) << 1;
dumyIn |= digitalRead (4) << 2;
dumyIn |= digitalRead (5) << 3;
digitalWrite (8, LOW); // clock falling
delay(2);
}
compilation : 1456 octets.
Maintenant, je remplace les fonctions Arduino par des accès aux registres :
void setup() {
DDRB |= 0x03; // R/W : PB0; clock : PB1
}
byte dumyIn; // variable de lecture
byte dumyOut; // variable d'écriture
void loop() {
// -----------------Write data---------
DDRD |= 0x3C; // data(3:0) output
PORTB &= 0xFD; // Write data
dumyOut &= 0x0F; // mask dumyOut
dumyOut << 2;
PORTD &= 0xC3; // set data = 0;
PORTD |= dumyOut; // set data;
PORTB |= 0x01; // clock rising
delay(2);
PORTB &= 0xFE; // clock falling
// -----------------Read data---------
DDRD &= 0xC3; // data(3:0) input
PORTB |= 0x02; // Read data
PORTB |= 0x01; // clock rising
delay(2);
dumyIn = (PIND & 0x3C);
dumyIn >> 2;
PORTB &= 0xFE; // clock falling
delay(2);
}
compilation : 724 octets j'ai donc divisé par deux la taille de mon programme, et à mon avis (j'ai pas testé), il doit aller... 10 fois plus vite?
Même code registres, mais en remplaçant (je pensais simplifier le code) :
dumyIn = (PIND & 0x3C);
dumyIn >> 2;
par :
dumyIn = (PIND & 0x3C) >> 2;
compilation : 736 octets : j'ai perdu 12 octets (donc 6 instructions ASM supplémentaires...), juste en réécrivant deux lignes en une seule! De plus, cela doit certainement influer sur la RAM en passant par une variable de passage pour calculer l'opération entre parenthèses...
Je remplace alors ce bout de code par :
dumyIn = PIND;
dumyIn &= 0x3C;
dumyIn >> 2;
et reviens à ma compilation de 724 octets.
Conclusion, si on veut du programme rapide et léger en flash, on évitera les fonctions Arduino et les lignes à opérations multiples!
Je n'ai pas le temps de tester pour mesurer les signaux, mais j'essaierai... (un coup d'oscillo sur la pin R/W pour mesurer la période nous donnera le temps que prend la boucle Loop()).