pave Interruptions6 Interruptions4 INTERRUPTIONS
5/7


ATTINY861


DESCRIPTION

cet article décrit l'utilisation des interruptions sur la puce attiny861. Un exemple avec six 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'ATTiny861 avec un triplement des possibilités.
Les modes ON / OFF avec détection du Front Montant et Descendant, et interrupteur Marche / Arrêt seront à extraire 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 261/461/861 and 261V/461V/861V - @Alain DORING (2020) - https://www.astrolynx.com/
   ┌───────────────────────────────────────── SPI ───────────────────────────────────────────┐
   │                                ┌─────── ANALOG ──────┐                                  │
   │                                │  ┌─── DIGITAL ───┐  │                                  │
   │                                │  │    ┌─┐_┌─┐    │  │                                  │
 VERT          MOSI/SDA/PCINT8 PB0     8   1│o    │20  0  0   PA0 PCINT0/ADC0
 BLEU              MISO/PCINT9 PB1     9   2│     │19  1  1   PA1 PCINT1/ADC1
 BLANC    SCK/USCK/SCL/PCINT10 PB2     10  3│     │18  2  2   PA2 PCINT2/ADC2/INT1 
                       PCINT11 PB3     11  4│     │17  3      PA3 PCINT3/AREF
 ROUGE                         VCC         5│     │16         AGND
 NOIR                          GND         6│     │15         AVCC
             CLKI/ADC7/PCINT12 PB4  7  12  7│     │14  4  3   PA4 PCINT4/ADC3
             CLKO/ADC8/PCINT13 PB5  8  13  8│     │13  5  4   PA5 PCINT5/ADC4/AIN2
             INT0/ADC9/PCINT14 PB6  9  14  9│     │12  6  5   PA6 PCINT6/ADC5/AIN0
 JAUNE     RESET/ADC10/PCINT15 PB7  10    10│     │11  7  6   PA7 PCINT7/ADC6/AIN1
                                            └─────┘           

 Vecteurs externes                 INT0_vect  -  INT1_vect
 Vecteurs de changement de broches PCINT_vect

 BITS --►   7       6       5       4       3       2       1       0
 GIMSK  - INT1    INT0    PCIE1   PCIE0                          
 GIFR   - INTF1   INTF0   PCIF                                   
 PCMSK0 - PCINT7  PCINT6  PCINT5  PCINT4  PCINT3  PCINT2  PCINT1  PCINT0 
 PCMSK1 - RESET   PCINT14 PCINT13 PCINT12 PCINT11 PCINT10 PCINT9  PCINT8 
 PORTA  - PORTA6  PORTA6  PORTA5  PORTA4  PORTA3  PORTA2  PORTA1  PORTA0
 DDRA   - DDA7    DDA6    DDA5    DDA4    DDA3    DDA2    DDA1    DDA0
 PINA   - PINA7   PINA6   PINA5   PINA4   PINA3   PINA2   PINA1   PINA0
 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
 WDTCR  - WDIF    WDIE    WDP3    WDCE    WDE     WDP2    WDP1    WDP0
 WDT    0x000C    

                 „       1K     ┌────────────┐    1K      „
  LED BLEUE  ┌──┤◄├────/\/\/\──◄│ PB0    PA0 │►─/\/\/\───┤►├───┐ LED BLANCHE
 CLIGNOTANTE │                  │            │                 │ CLIGNOTANTE 
             │   „       1K     │            │           _▄▄_  │ 
  LED JAUNE  ├──┤◄├────/\/\/\──◄│ PB1    PA1 │◄──────────O  O──┤ BP > LED PB1 
             │                  │            │                 │ 
             │   „       1K     │            │           _▄▄_  │ 
  LED ORANGE ├──┤◄├────/\/\/\──◄│ PB2    PA2 │◄──────────O  O──┤ BP > LED PB2 
             │                  │            │                 │ 
             │   „       1K     │            │           _▄▄_  │ 
  LED ROUGE  ├──┤◄├────/\/\/\──◄│ PB3    PA3 │◄──────────O  O──┤ BP > LED PB3 
             │                  │            │                 │ 
             │                ─◄│ VCC   AGND │►─               │ 
             │                  │            │                 │  
             │                ─◄│ GND   AVCC │►─               │ 
             │   „       1K     │            │           _▄▄_  │  
  LED ROUGE  ├──┤◄├────/\/\/\──◄│ PB4    PA4 │◄──────────O  O──┤ BP > LED PA7 
             │                  │            │                 │ 
             │   „       1K     │            │           _▄▄_  │ 
  LED ORANGE ├──┤◄├────/\/\/\──◄│ PB5    PA5 │◄──────────O  O──┤ BP > LED PB5 
             │                  │            │                 │ 
             │   „       1K     │            │           _▄▄_  │ 
  LED VERTE  ├──┤◄├────/\/\/\──◄│ PB6    PA6 │◄──────────O  O──┤ BP > LED PB4 
 CLIGNOTANTE │                  │            │                 │ 
             │                  │            │    1K      „    │ 
 Non utilisé │          RESET ─◄│ PB7    PA7 │►─/\/\/\───┤►├───┤ LED JAUNE
             │                  └────────────┘                 │
             ┴                                                 ┴
            GND                                               GND
*/         

// Variables de stockage de l'état des boutons
volatile int oldEtatA1 = 0;
volatile int newEtatA1 = 0;
volatile int oldEtatA2 = 0;
volatile int newEtatA2 = 0;
volatile int oldEtatA3 = 0;
volatile int newEtatA3 = 0;
volatile int oldEtatA4 = 0;
volatile int newEtatA4 = 0;
volatile int oldEtatA5 = 0;
volatile int newEtatA5 = 0;
volatile int oldEtatA6 = 0;
volatile int newEtatA6 = 0;


ISR (PCINT_vect)
{
  newEtatA1 = (PINA & B00000010);   // digitalRead(1);
  newEtatA2 = (PINA & B00000100);   // digitalRead(2);
  newEtatA3 = (PINA & B00001000);   // digitalRead(3);
  newEtatA4 = (PINA & B00010000);   // digitalRead(4);
  newEtatA5 = (PINA & B00100000);   // digitalRead(5);
  newEtatA6 = (PINA & B01000000);   // digitalRead(6);

  // Détection d'un changement d'état PA1
  if (oldEtatA1 != newEtatA1) {
    if (newEtatA1 == 1) {
      // Traitement du front montant
      PORTB ^= (1 << PB1);  // bascule la broche PB1 si changement logique PCINT1
    }
    else {
      PORTB ^= (1 << PB1);  // bascule la broche PB1 si changement logique PCINT1
      // Traitement du front descendant
    }
    oldEtatA1 = newEtatA1;
  }

  // Détection d'un changement d'état PA2
  if (oldEtatA2 != newEtatA2) {
    if (newEtatA2 == 1) {
      // Traitement du front montant
      PORTB ^= (1 << PB2);  // bascule la broche PB2 si changement logique PCINT2
    }
    else {
      PORTB ^= (1 << PB2);  // bascule la broche PB2 si changement logique PCINT2
      // Traitement du front descendant
    }
    oldEtatA2 = newEtatA2;
  }

  // Détection d'un changement d'état PA3
  if (oldEtatA3 != newEtatA3) {
    if (newEtatA3 == 1) {
      // Traitement du front montant
      PORTB ^= (1 << PB3);  // bascule la broche PB3 si changement logique PCINT3
    }
    else {
      PORTB ^= (1 << PB3);  // bascule la broche PB3 si changement logique PCINT3
      // Traitement du front descendant
    }
    oldEtatA3 = newEtatA3;
  }

  // Détection d'un changement d'état PA4
  if (oldEtatA4 != newEtatA4) {
    if (newEtatA4 == 1) {
      // Traitement du front montant
      PORTA ^= (1 << PA7);  // bascule la broche PA7 si changement logique PCINT4
    }
    else {
      PORTA ^= (1 << PA7);  // bascule la broche PA7 si changement logique PCINT4
      // Traitement du front descendant
    }
    oldEtatA4 = newEtatA4;
  }

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

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

}

void setup() {
  // initialisation du PORTA en entrées ou en sorties = 8 x Pinmode(pin, INPUT ou OUTPUT) 
  DDRA   =  B10000001;      // active PA -> 1 en sorties et 0 en entrée (PA1 à PA6)
  // initialisations du PORTB en entrées ou en sorties = 8 x Pinmode(pin, INPUT ou OUTPUT) 
  DDRB   =  B01111111;      // active PB -> 1 en sorties sauf PB7 (RESET)

  // initialisations des PULLUPs = 6 x Pinmode(pin, INPUT_PULLUP) 
  PORTA |=  B01111110;      // active le pullup PA1 à P6 pour les Boutons Poussoirs

  // Activation des ports A et B 
  GIMSK   = B00110000;      // active interruptions de changement de broche PCIE0 & PCIE1

  // Déclaration des broches d'interruptions
  PCMSK0 |= B01111110;      // changement de broche activée pour PA1 à PA6

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

  // Inversion logique des 6 leds commandées par les BPs sinon démarrent allumées
  PORTA ^= B10000000;       // bascule PA7 pour inverser la logique
  PORTB ^= B00111110;       // bascule PB1 à PB5 pour inverser la logique

  // Initialisations des routines d'interruptions pour forcer le démarrage leds éteintes
  PCINT_vect();             // Initialise la routine d'interruption pour PA1 à PA6     
  
}

void loop() {
  // mettre ici le code à répéter continuellement
  delay(500);
  PORTA ^= (1 << PA0);      // Led clignotante bleue
  PORTB ^= (1 << PB0);      // Led clignotante blanche
  PORTB ^= (1 << PB6);      // 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. Les annotations A0..A7 et B0..B6 sont à lire PA0..PA7 et PB0..PB6. La broche PB7, notée RST pour RESET, n'est pas utilisée.

VIDÉO

Cette vidéo montre le fonctionnement des interruptions sur un ATTiny861.
La led jaune PB1 commandée par le bouton poussoir PA1.
La led orange PB2 commandée par le bouton poussoir PA2.
La led rouge PB3 commandée par le bouton poussoir PA3.
La led jaune PA7 commandée par le bouton poussoir PA4.
La led orange PB5 commandée par le bouton poussoir PA5.
La led rouge PB4 commandée par le bouton poussoir PA6.
Les leds blanche PA0, bleue PB0 et verte PB6 dont le clignotement est assuré dans la boucle LOOP.

Télécharger les codes Interrupt_ATTiny861