Il existe deux types d'interruptions de type "changement de broche". Les interruptions externes, dont il y en a deux sur l'Uno. Ils sont appelés 0 et 1, mais ils se réfèrent aux broches numériques 2 et 3 de la carte. Ceux-ci peuvent être configurés pour détecter une hausse, une baisse, un changement (ascendant ou descendant) ou BAS.
En plus de cela, des interruptions de "changement de broche", qui détectent un changement de l'état de broche dans l'une des 20 broches (A0 à A5 et D0 à D13). Ces interruptions de changement de broches sont également basées sur le matériel , elles seront donc aussi rapides que les interruptions externes.
Les deux types sont légèrement difficiles à utiliser au niveau du registre, mais l'IDE standard comprend attachInterrupt (n) et detachInterrupt (n) qui simplifie l'interface avec les interruptions externes. Vous pouvez également utiliser la bibliothèque de changements de broches pour simplifier les interruptions de changement de broches.
Cependant, en évitant la bibliothèque pendant une minute, nous pouvons établir que les interruptions de changement de broche peuvent être aussi rapides, ou plus rapides, que les interruptions externes. D'une part, bien que les interruptions de changement de broches fonctionnent sur des lots de broches, vous n'avez pas besoin d'activer le lot entier. Par exemple, si vous souhaitez détecter des modifications sur la broche D4, cela suffira:
Exemple d'esquisse:
ISR (PCINT2_vect)
{
// handle pin change interrupt for D0 to D7 here
if (PIND & bit (4)) // if it was high
PORTD |= bit (5); // turn on D5
else
PORTD &= ~bit (5); // turn off D5
} // end of PCINT2_vect
void setup ()
{
// pin change interrupt (example for D4)
PCMSK2 |= bit (PCINT20); // want pin 4
PCIFR |= bit (PCIF2); // clear any outstanding interrupts
PCICR |= bit (PCIE2); // enable pin change interrupts for D0 to D7
pinMode (4, INPUT_PULLUP);
pinMode (5, OUTPUT);
} // end of setup
void loop ()
{
}
Mes tests indiquent qu'il a fallu 1,6 µs pour que la broche "test" (broche 5) réagisse à un changement sur la broche d'interruption (broche 4).
Maintenant, si vous adoptez l'approche simple (paresseux?) Et utilisez attachInterrupt (), vous constaterez que les résultats sont plus lents et non plus rapides.
Exemple de code:
void myInterrupt ()
{
if (PIND & bit (2)) // if it was high
PORTD |= bit (5); // turn on D5
else
PORTD &= ~bit (5); // turn off D5
} // end of myInterrupt
void setup ()
{
attachInterrupt (0, myInterrupt, CHANGE);
pinMode (2, INPUT_PULLUP);
pinMode (5, OUTPUT);
} // end of setup
void loop ()
{
}
Cela prend 3,7 µs pour changer la broche de test, beaucoup plus que les 1,6 µs ci-dessus. Pourquoi? Parce que le code que le compilateur doit générer pour le gestionnaire d'interruption "générique" doit enregistrer tous les registres imaginables (les pousser) à l'entrée dans l'ISR, puis les restaurer (les faire éclater) avant de revenir. De plus, il y a la surcharge d'un autre appel de fonction.
Maintenant, nous pouvons contourner cela en évitant attachInterrupt () et en le faisant nous-mêmes:
ISR (INT0_vect)
{
if (PIND & bit (2)) // if it was high
PORTD |= bit (5); // turn on D5
else
PORTD &= ~bit (5); // turn off D5
} // end of INT0_vect
void setup ()
{
// activate external interrupt 0
EICRA &= ~(bit(ISC00) | bit (ISC01)); // clear existing flags
EICRA |= bit (ISC00); // set wanted flags (any change interrupt)
EIFR = bit (INTF0); // clear flag for interrupt 0
EIMSK |= bit (INT0); // enable it
pinMode (2, INPUT_PULLUP);
pinMode (5, OUTPUT);
} // end of setup
void loop ()
{
}
C'est le plus rapide de tous à 1,52 µs - il semble qu'un cycle d'horloge ait été enregistré quelque part.
Il y a cependant une mise en garde pour les interruptions de changement de broche. Ils sont groupés, donc si vous voulez avoir des interruptions sur beaucoup de broches, vous devez tester à l'intérieur de l'interruption laquelle a changé. Vous pouvez le faire en enregistrant le statut de broche précédent et en le comparant au nouveau statut de broche. Ce n'est pas nécessairement particulièrement lent, mais plus il vous faudra vérifier de broches, plus ce serait lent.
Les lots sont:
Si vous voulez juste quelques broches d'interruption supplémentaires, vous pouvez éviter tout test en choisissant simplement d'utiliser des broches de différents lots (par exemple, D4 et D8).
Plus de détails sur http://www.gammon.com.au/interrupts