pave Interruptions7 Interruptions5 INTERRUPTIONS
6/7


ATTINY88


DESCRIPTION

cet article décrit l'utilisation des interruptions sur la puce attiny88. Un exemple avec dix boutons poussoirs en mode momentané ON / OFF est décrit dans cette page. Le code est strictement identique à celui de l'ATTiny85 mais adapté pour l'ATTiny88 avec une multiplication par 5 des possibilités.
Les modes ON / OFF avec détection du Front Montant et Descendant, et interrupteur Marche / Arrêt seront à déduire des codes de l'ATTiny85. Il faut bien que je vous laisse un peu de travail...

ENTÊTE

L'entête aura une structure identique et adaptée à chaque puce.

CODE

La structure du code (le programme à proprement parler) sera toujours la même.

/* ATMEL ATTINY 48/88 - @Alain DORING (2020) - https://www.astrolynx.com/ - Original source
   ┌───────────────────────────────────────── SPI ───────────────────────────────────────────┐
   │                                ┌─────── ANALOG ──────┐                                  │
   │                                │  ┌─── DIGITAL ───┐  │                                  │
   │                                │  │    ┌─┐_┌─┐    │  │                                  │
 JAUNE           RESET/PCINT14 PC6     27  1│o    │28 22  5   PC5 PCINT13/ADC5/SCL
                       PCINT16 PD0     0   2│     │27 21  4   PC4 PCINT12/ADC4/SDA
                       PCINT17 PD1     1   3│     │26 20  3   PC3 PCINT11/ADC3/INT1
                  INT0/PCINT18 PD2     2   4│     │25 19  2   PC2 PCINT10/ADC2
                  INT1/PCINT19 PD3     3   5│     │24 18  1   PC1 PCINT9 /ADC1
                    T0/PCINT20 PD4     4   6│     │23 17  0   PC0 PCINT8 /ADC0
 ROUGE                         VCC         7│     │22         GND
 NOIR                          GND         8│     │21 16      PC7 PCINT15
                        PCINT6 PB6     14  9│     │20         AVCC/AREF
                        PCINT7 PB7     15 10│     │19 13      PB5 PCINT5 /SCK               BLANC
                    T1/PCINT21 PD5     5  11│     │18 12      PB4 PCINT4 /DO/MISO           BLEU
                  AIN0/PCINT22 PD6     6  12│     │17 11      PB3 PCINT3 /DI/MOSI/          VERT
                  AIN1/PCINT23 PD7     7  13│     │16 10      PB2 PCINT2 /ADC5/
                        PCINT0 PB0     8  14│     │15  9      PB1 PCINT1 /ADC6/
                                            └─────┘

 Vecteurs externes                 INT0_vect   - INT1_vect
 Vecteurs de changement de broches PCINT0_vect - PCINT1_vect - PCINT2_vect
                                 - PCINT3_vect - Non utilisé dans le boîtier DIP 28 broches

 BITS --►   7       6       5       4       3       2       1       0

 GIMSK & GIFR  ont disparus du paysage remplacés par les 4 lignes suivantes

 EIMSK  -                                                 INT1    INT0
 EIFR   -                                                 INTF1   INTF0
 PCIFR  -                                         PCIF2   PCIF1   PCIF0
 PCICR  -                                         PCIE2   PCIE1   PCIE0

 PCMSK0 - PCINT7  PCINT6  PCINT5  PCINT4  PCINT3  PCINT2  PCINT1  PCINT0
 PCMSK1 - PCINT15 RESET   PCINT13 PCINT12 PCINT11 PCINT10 PCINT9  PCINT8
 PCMSK2 - PCINT23 PCINT22 PCINT21 PCINT20 PCINT19 PCINT18 PCINT17 PCINT16

 PCMSK3, PORTA, DDRA, PINA non utilisés dans le boîtier DIP 28 broches

 PORTB  - PORTB7  PORTB6  PORTB5  PORTB4  PORTB3  PORTB2  PORTB1  PORTB0
 DDRB   - DDB7    DDB6    DDB5    DDB4    DDB3    DDB2    DDB1    DDB0
 PINB   - PINB7   PINB6   PINB5   PINB4   PINB3   PINB2   PINB1   PINB0
 PORTC  - PORTC7  PORTC6  PORTC5  PORTC4  PORTC3  PORTC2  PORTC1  PORTC0
 DDRC   - DDC7    DDC6    DDC5    DDC4    DDC3    DDC2    DDC1    DDC0
 PINC   - PINC7   PINC6   PINC5   PINC4   PINC3   PINC2   PINC1   PINC0
 PORTD  - PORTD7  PORTD6  PORTD5  PORTD4  PORTD3  PORTD2  PORTD1  PORTD0
 DDRD   - DDD7    DDD6    DDD5    DDD4    DDD3    DDD2    DDD1    DDD0
 PIND   - PIND7   PIND6   PIND5   PIND4   PIND3   PIND2   PIND1   PIND0
 WDTCSR - WDIF    WDIE    WDP3    WDCE    WDE     WDP2    WDP1    WDP0
 WDT    0x000C

                                ┌────────────┐           _▄▄_                
 Non utilisé           RESET ──◄│ PC6    PC5 │◄──────────O  O──┐ BP > LED PD4
                                │            │                 │             
                 „       1K     │            │           _▄▄_  │             
  LED BLEUE  ┌──┤◄├────/\/\/\──◄│ PD0    PC4 │◄──────────O  O──┤ BP > LED PD3
 CLIGNOTANTE │                  │            │                 │             
             │   „       1K     │            │           _▄▄_  │             
  LED JAUNE  ├──┤◄├────/\/\/\──◄│ PD1    PC3 │◄──────────O  O──┤ BP > LED PD2
             │                  │            │                 │             
             │   „       1K     │            │           _▄▄_  │             
  LED ORANGE ├──┤◄├────/\/\/\──◄│ PD2    PC2 │◄──────────O  O──┤ BP > LED PD1
             │                  │            │                 │             
             │   „       1K     │            │           _▄▄_  │             
  LED ROUGE  ├──┤◄├────/\/\/\──◄│ PD3    PC1 │◄──────────O  O──┤ BP > LED PC7
             │                  │            │                 │             
             │   „       1K     │            │    1K      „    │ LED BLANCHE 
  LED VERTE  ├──┤◄├────/\/\/\──◄│ PD4    PC0 │►─/\/\/\───┤►├───┤ CLIGNOTANTE 
             │                  │            │                 │             
             │                ─◄│ VCC    GND │►─               │             
             │                  │            │    1K      „    │             
             │                ─◄│ GND    PC7 │►─/\/\/\───┤►├───┤ LED BLANCHE 
             │   „       1K     │            │                 │             
 LED BLANCHE ├──┤◄├────/\/\/\──◄│ PB6   AVCC │►─               │             
             │                  │            │                 │             
             │   „       1K     │            │           _▄▄_  │             
  LED JAUNE  ├──┤◄├────/\/\/\──◄│ PB7    PB5 │◄──────────O  O──┤ BP > LED PB6
             │                  │            │                 │             
             │   „       1K     │            │           _▄▄_  │             
  LED ORANGE ├──┤◄├────/\/\/\──◄│ PD5    PB4 │◄──────────O  O──┤ BP > LED PB7
             │                  │            │                 │             
             │   „       1K     │            │           _▄▄_  │             
  LED ROUGE  ├──┤◄├────/\/\/\──◄│ PD6    PB3 │◄──────────O  O──┤ BP > LED PD5
             │                  │            │                 │             
             │   „       1K     │            │           _▄▄_  │             
  LED VERTE  ├──┤◄├────/\/\/\──◄│ PD7    PB2 │◄──────────O  O──┤ BP > LED PD6
             │                  │            │                 │             
             │   „       1K     │            │           _▄▄_  │             
  LED VERTE  ├──┤◄├────/\/\/\──◄│ PB0    PB1 │◄──────────O  O──┤ BP > LED PD7
 CLIGNOTANTE │                  └────────────┘                 │             
             │                                                 │             
             ┴                                                 ┴             
            GND                                               GND            
*/                                                                           

// Variables de stockage de l'état des boutons                               
volatile int oldEtatB1 = 0;                                                  
volatile int newEtatB1 = 0;                                                  
volatile int oldEtatB2 = 0;                                                  
volatile int newEtatB2 = 0;                                                  
volatile int oldEtatB3 = 0;                                                  
volatile int newEtatB3 = 0;                                                  
volatile int oldEtatB4 = 0;                                                  
volatile int newEtatB4 = 0;                                                  
volatile int oldEtatB5 = 0;                                                  
volatile int newEtatB5 = 0;                                                  
volatile int oldEtatC1 = 0;                                                  
volatile int newEtatC1 = 0;                                                  
volatile int oldEtatC2 = 0;                                                  
volatile int newEtatC2 = 0;                                                  
volatile int oldEtatC3 = 0;                                                  
volatile int newEtatC3 = 0;                                                  
volatile int oldEtatC4 = 0;                                                  
volatile int newEtatC4 = 0;                                                  
volatile int oldEtatC5 = 0;                                                  
volatile int newEtatC5 = 0;                                                  


ISR (PCINT0_vect)                                                            
{                                                                            
  newEtatB1 = (PINB & B00000010);   // digitalRead(9);                       
  newEtatB2 = (PINB & B00000100);   // digitalRead(10);                      
  newEtatB3 = (PINB & B00001000);   // digitalRead(11);                      
  newEtatB4 = (PINB & B00010000);   // digitalRead(12);                      
  newEtatB5 = (PINB & B00100000);   // digitalRead(13);                      

  // Détection d'un changement d'état PB1                                    
  if (oldEtatB1 != newEtatB1) {                                              
    if (newEtatB1 == 1) {                                                    
      // Traitement du front montant                                         
      PORTD ^= (1 << PD7);  // bascule la broche PD7 si changement logique PB1
    }                                                                         
    else {                                                                    
      PORTD ^= (1 << PD7);  // bascule la broche PD7 si changement logique PB1
      // Traitement du front descendant                                       
    }                                                                         
    oldEtatB1 = newEtatB1;                                                    
  }

  // Détection d'un changement d'état PB2                                     
  if (oldEtatB2 != newEtatB2) {                                               
    if (newEtatB2 == 1) {                                                     
      // Traitement du front montant                                          
      PORTD ^= (1 << PD6);  // bascule la broche PD6 si changement logique PB2
    }                                                                         
    else {                                                                    
      PORTD ^= (1 << PD6);  // bascule la broche PD6 si changement logique PB2
      // Traitement du front descendant                                       
    }                                                                         
    oldEtatB2 = newEtatB2;                                                    
  }

  // Détection d'un changement d'état PB3                                     
  if (oldEtatB3 != newEtatB3) {                                               
    if (newEtatB3 == 1) {                                                     
      // Traitement du front montant                                          
      PORTD ^= (1 << PD5);  // bascule la broche PD5 si changement logique PB3
    }                                                                         
    else {                                                                    
      PORTD ^= (1 << PD5);  // bascule la broche PD5 si changement logique PB3
      // Traitement du front descendant                                       
    }                                                                         
    oldEtatB3 = newEtatB3;                                                    
  }

  // Détection d'un changement d'état PB4                                     
  if (oldEtatB4 != newEtatB4) {                                               
    if (newEtatB4 == 1) {                                                     
      // Traitement du front montant                                          
      PORTB ^= (1 << PB7);  // bascule la broche PB7 si changement logique PB4
    }                                                                         
    else {                                                                    
      PORTB ^= (1 << PB7);  // bascule la broche PB7 si changement logique PB4
      // Traitement du front descendant                                       
    }                                                                         
    oldEtatB4 = newEtatB4;                                                    
  }

  // Détection d'un changement d'état PB5                                     
  if (oldEtatB5 != newEtatB5) {                                               
    if (newEtatB5 == 1) {                                                     
      // Traitement du front montant                                          
      PORTB ^= (1 << PB6);  // bascule la broche PB6 si changement logique PB5
    }                                                                         
    else {                                                                    
      PORTB ^= (1 << PB6);  // bascule la broche PB6 si changement logique PB5
      // Traitement du front descendant                                       
    }                                                                         
    oldEtatB5 = newEtatB5;                                                    
  }                                                                           
}

ISR (PCINT1_vect)                                                             
{                                                                             
  newEtatC1 = (PINC & B00000010);   // digitalRead(18);                       
  newEtatC2 = (PINC & B00000100);   // digitalRead(19);                       
  newEtatC3 = (PINC & B00001000);   // digitalRead(20);                       
  newEtatC4 = (PINC & B00010000);   // digitalRead(21);                       
  newEtatC5 = (PINC & B00100000);   // digitalRead(22);                       

  // Détection d'un changement d'état PC1                                     
  if (oldEtatC1 != newEtatC1) {                                               
    if (newEtatC1 == 1) {                                                     
      // Traitement du front montant                                          
      PORTC ^= (1 << PC7);  // bascule la broche PC7 si changement logique PC1
    }                                                                         
    else {                                                                    
      PORTC ^= (1 << PC7);  // bascule la broche PC7 si changement logique PC1
      // Traitement du front descendant                                       
    }                                                                         
    oldEtatC1 = newEtatC1;                                                    
  }

  // Détection d'un changement d'état PC2                                     
  if (oldEtatC2 != newEtatC2) {                                               
    if (newEtatC2 == 1) {                                                     
      // Traitement du front montant                                          
      PORTD ^= (1 << PD1);  // bascule la broche PD1 si changement logique PC2
    }                                                                         
    else {                                                                    
      PORTD ^= (1 << PD1);  // bascule la broche PD1 si changement logique PC2
      // Traitement du front descendant                                       
    }                                                                         
    oldEtatC2 = newEtatC2;                                                    
  }

  // Détection d'un changement d'état PC3                                     
  if (oldEtatC3 != newEtatC3) {                                               
    if (newEtatC3 == 1) {                                                     
      // Traitement du front montant                                          
      PORTD ^= (1 << PD2);  // bascule la broche PD2 si changement logique PC3
    }                                                                         
    else {                                                                    
      PORTD ^= (1 << PD2);  // bascule la broche PD2 si changement logique PC3
      // Traitement du front descendant                                       
    }                                                                         
    oldEtatC3 = newEtatC3;                                                    
  }                                                                           

  // Détection d'un changement d'état PC4                                     
  if (oldEtatC4 != newEtatC4) {                                               
    if (newEtatC4 == 1) {                                                     
      // Traitement du front montant                                          
      PORTD ^= (1 << PD3);  // bascule la broche PD3 si changement logique PC4
    }                                                                         
    else {                                                                    
      PORTD ^= (1 << PD3);  // bascule la broche PD3 si changement logique PC4
      // Traitement du front descendant                                       
    }                                                                         
    oldEtatC4 = newEtatC4;                                                    
  }                                                                           

  // Détection d'un changement d'état PC5                                     
  if (oldEtatC5 != newEtatC5) {                                               
    if (newEtatC5 == 1) {                                                     
      // Traitement du front montant                                          
      PORTD ^= (1 << PD4);  // bascule la broche PD4 si changement logique PC5
    }                                                                         
    else {                                                                    
      PORTD ^= (1 << PD4);  // bascule la broche PD4 si changement logique PC5
      // Traitement du front descendant                                       
    }                                                                         
    oldEtatC5 = newEtatC5;                                                    
  }                                                                           
}                                                                             


void setup() {                                                                
  // Initialisation du PORTB en entrées ou en sorties = 8 x Pinmode(pin, INPUT ou OUTPUT)
  DDRB   |= B11000001;      // active PB -> 1 en sortie et 0 en entrée (PB1 à PB5)
  // Initialisation du PORTC en entrées ou en sorties = 8 x Pinmode(pin, INPUT ou OUTPUT)
  DDRC   |= B10000001;      // active PC -> 1 en sortie et 0 en entrée (PC1 à PC5) et PC6 (RESET)
  // Initialisation du PORTD en entrées ou en sorties = 8 x Pinmode(pin, INPUT ou OUTPUT)
  DDRD   |= B11111111;      // active PD -> 1 en sortie
  // Notez  que PC6 (RESET) a été mis à 0

  // Initialisations des PULLUPs = 10 x Pinmode(pin, INPUT_PULLUP)                       
  PORTB  |= B00111110;      // active les pullups PB1 à PB5 pour les Boutons Poussoirs   
  PORTC  |= B00111110;      // active les pullups PC1 à PC5 pour les Boutons Poussoirs   

  // Activation des ports B et C - Remplace GIMSK
  PCICR  |= B00000011;      // Interruptions de changement de broche PCIE0 et PCIE1      

  // Déclaration des broches d'interruptions                                             
  PCMSK0 |= B00111110;      // changement de broche activée de PB1 à PB5                 
  PCMSK1 |= B00111110;      // changement de broche activée de PC1 & PC5                 

  // Activation globale des interruptions                                                
  sei ();                   // active les interruptions                                  

  // Inversion logique des 10 leds commandées par les BPs sinon démarrent allumées       
  PORTB  ^= B11000000;      // bascule PB6 & PB7 pour inverser la logique                
  PORTC  ^= B10000000;      // bascule PC7 pour inverser la logique                      
  PORTD  ^= B11111110;      // bascule PD1 à PD7 pour inverser la logique                

  // Initialisations des routines d'interruptions pour forcer le démarrage leds éteintes 
  PCINT0_vect();            // Initialise la routine d'interruption de PB1 à PB5         
  PCINT1_vect();            // Initialise la routine d'interruption de PC1 à PC5         

}                                                                                        


void loop() {                                                                            
  // mettre ici le code à répéter continuellement                                        
  delay(500);                                                                            
  PORTB ^= (1 << PB0);      // Led clignotante bleue                                     
  PORTC ^= (1 << PC0);      // Led clignotante blanche                                   
  PORTD ^= (1 << PD0);      // Led clignotante verte                                     
}                                                                                        

Téléchargement du code au bas de cette page

IMPLANTATION

Cette vue permet de voir l'implantation des composants sur une breadboard.

VIDÉO

Cette vidéo montre le fonctionnement des interruptions sur un ATTiny88.
La led jaune PD7 commandée par le bouton poussoir PB1.
La led orange PD6 commandée par le bouton poussoir PB2.
La led rouge PD5 commandée par le bouton poussoir PB3.
La led jaune PB7 commandée par le bouton poussoir PB4.
La led orange PB6 commandée par le bouton poussoir PB5.
La led rouge PC7 commandée par le bouton poussoir PC1.
La led orange PD1 commandée par le bouton poussoir PC2.
La led rouge PD2 commandée par le bouton poussoir PC3.
La led jaune PD3 commandée par le bouton poussoir PC4.
La led orange PD4 commandée par le bouton poussoir PC5.
Les leds verte PB0, blanche PC0 et bleue PD0 dont le clignotement est assuré dans la boucle LOOP.

Télécharger les codes Interrupt_ATTiny88