Exemple 10 : Utilisation de la sortie "MLI automatique" : OC1A Schéma identique à l'exercice précédent. - Attention, la sortie OC1A est située sur la patte B1 (voir le Datasheet du µC) -On met les entrées d'interrupteurs sur B2 et B3 |
![]() |
Solution : L'interruption ne se déclenchera que lors du débordement (OVF pour "Overflow") pour mettre à jour OCR1A (en fonction des BP sollicités) Cette fois, c'est le port B qui a sa patte "1" en sortie TCCR1A et TCCR1D définissent le comportement du port B1. Avec ces réglages, il sera mis à 1 lors du débordement puis mis à zéro lors de la comparaison avec OCR1A. Tout cela AUTOMATIQUEMENT ! ==> TIMSK =0b00000100 (ok pour interruption débordement) Pendant ce temps, le µC est LIBRE ! |
![]() |
On obtient EXACTEMENT le même comportement qu'à l'exemple 9.![]() Mais cette fois ci, ce n'est plus le coeur qui gère les mises à "1" ou à "0". C'est le timer qui fait cela en automatique. Le coeur du µC est libre et il n'y a aucun risque de "petit" contretemps. ![]() |
Exemple 11 : Détection des évènements externes On reprend l'exercice 5, mais cette fois, - Le BP "Start" devra être relié à B6 (INT0).
(Le schéma ci-contre doit donc être modifié en conséquence !!!!)- Le BP "Stop" devra être relié à A2 (INT1). |
![]() (schéma de l'exemple 5)
|
La variable "Memoire" servira à mémoriser le dernier appui effectué. Deux sous-programmes d'interruptions (un pour INT0 et un pour INT1) vont permettre de gérer différemment chaque évènement. Ils sont TRES courts !!!! - Au moment de l'initialisation, on a besoin d'une ligne supplémentaire pour autoriser le déclenchement des interruptions INT0 et INT1. Avec le registre GIMSK, le premier "1" c'est pour INT1, le second c'est pour INT0. - MCUCR=3 permet de ne réagir qu'aux fronts montants. La boucle principale est encore disponible pour d'autres tâches de calcul ! Cool ! |
![]() |
Exemple 12 : Mesure d'une durée. Dans le montage ci-contre, l'optocoupleur permet de détecter les créneaux du signal DCC - Un créneau "long" dure 220µs ==> DCC=0 - Un créneau "court" dure 116µs ==> DCC=1 Il faut donc mesurer la durée du créneau pour connaître la valeur de l'info transmise. |
![]() |
Dès
que l'interruption est déclenchée : - on consulte le chronomètre. S'il est inférieur à 160µs alors c'est un créneau court : DCC=1. Sinon DCC=0 - On remet le compteur à zéro pour chronométrer le créneau suivant. - TCCR1B=5 : On règle le Timer 1 de façon à augmenter d'un cran à chaque microseconde. La valeur du Timer est ainsi égale au temps en microseconde. - MCUCR =3 : Pour que l'interruption INT0 (et donc la mesure) ne soit déclenchée que par les fronts montants. |
![]() |
Aperçu du signal avec l'oscilloscope :
Un créneau long dans les rails provoque une information "0" tandis qu'un créneau court provoque une sortie à "1" ![]() |
![]() |
Adresse de la case identifiée : "0000" & "01"
==> 0x000001 = 1 (hexadécimal) (décimal) |
![]() |
Valeurs placées : hexadécimal=> binaire 0x01 => 0000 0001 0x02 => 0000 0010 0x04 => 0000 0100 0x08 => 0000 1000 0x10 => 0001 0000 0x20 => 0010 0000 0x40 => 0100 0000 0x80 => 1000 0000 |
Exemple14 : Lecture de l'EEPROM On souhaite afficher successivement les 7 valeurs de l'EEPROM (rentrées ci-dessus) vers le portA. Le changement s'effectue toutes les 0.5s grâce au Timer0 réglé comme dans l'exemple 5. Les valeurs programmées ci-dessus vont afficher un chenillard qui va de A0 vers A7 et qui recommence. |
![]() |
On commence par définir une variable qui servira de "pointeur" d'adresse. Le sous-programme effectue les actions suivantes - RAZ du compteur (pour le respect du temps) - Incrémentation de la variable "pointeur" - Ecriture sur le port A de la valeur située en EEPROM à l'adresse du "pointeur" Remarquez que : - Tout le port A est en sortie DDRA=255 - Il est possible d'accélérer le rythme en diminuant les valeurs de OCR0A et OCR0B. OCR0B & OCR0A = 0000010001111010 L'octet OCR0B étant l'octet de poids fort, il aura beaucoup plus d'influence que OCR0A Et en attendant, le coeur peut faire autre-chose. |
![]() |
Exemple15 : Ecriture dans l'EEPROM Chaque appui sur le bouton poussoir fait avancer le chenillard d'un cran. En cas de disparition de l'alimentation, on doit mémoriser l'état des LEDs en EEPROM. Le bouton poussoir est branché sur la broche B6 pour solliciter l'interruption Int0. |
![]() |
L'interruption exécute trois actions : - "while(PINB6_bit)" permet d'attendre que l'utilisateur relâche le bouton poussoir pour éviter les rebonds de l'interrupteur. - La valeur du PORTA est incrémentée pour déplacer l'allumage d'un cran - On écrit dans l'EEPROM, à l'adresse 0x01 la valeur du portA. Au moment de l'initialisation, on va lire le contenu de l'EEPROM pour retrouver la dernière valeur écrite à l'adresse 0x01. Et en attendant, le corps du programme peut s'occuper d'autre chose. car tout se passe pendant les interruptions. |
![]() |