Interrupções Externas

Interrupção (IRQs) é uma maneira de iniciar rotinas de software em resposta a eventos eletrônicos assíncronos, ou seja, permite que um microcontrolador (assim como sistemas operacionais) responda a um evento qualquer, tratando esse evento como prioridade.  O processamento da interrupção compõe uma troca de contexto para uma rotina de software especifica para tratar a interrupção. A sequencia de como um processador irá tratar uma interrupção pode é descrita na sequencia e mostrada na figura 1.

      - Um sinal é gerado por um periférico gerando uma interrupção;
      - Após o término da instrução corrente, o processador identifica o pedido de interrupção;
      - Os conteúdos dos registradores, PC e status são salvos;
      - O processador identifica qual é a rotina de tratamento para aquela interrupção e carrega o PC  
         com o endereço inicial da rotina;
      - A rotina é executada;
      - Após o termino da execução da rotina interrupção, os registradores de uso geral são restaurados, além do registrador de status e o PC, retornando a execução do programa interrompido.


Figura 1. Esquema do processador tratando uma interrupção.

O Arduíno possui tanto interrupções internas que podem ser geradas a partir de um Timer e as interrupções externas que podem ser geradas a partir de um periférico externo. Nesta postagem iremos tratar interrupções externas. Para entender melhor o funcionamento da interrupção, iremos trabalhar com o circuito da figura 2 onde teremos 4 LEDs que acendem sequencialmente e um botão que irá gerar a interrupção da sequencia de acendimento dos LEDs. 

Figura 2. Circuito proposto para experiencia. 
Para executar o exemplo acima, a função loop ficará conforme código abaixo:

          void loop()
          {
             Serial.print(digitalRead(3));
            digitalWrite(10, LOW);
            digitalWrite(13, HIGH);
            delay(1000); 
            digitalWrite(13, LOW);
            digitalWrite(12, HIGH);
            delay(1000); 
            digitalWrite(12, LOW);
            digitalWrite(11, HIGH);
            delay(1000);
            digitalWrite(11, LOW);
            digitalWrite(10, HIGH);
            delay(1000); 
          }

Quando vamos trabalhar com interrupções, é necessário definir o que será processado quando uma interrupção for solicitada e criar uma função com as instruções que deverão ser processadas. No nosso exemplo, quando o botão for pressionado, a sequencia de acendimento dos LEDs será interrompida e todos os LEDs ficaram 5s apagados. Para executar esse procedimento, nossa função ficará da seguinte maneira:

          void interrupcao()
          {
            digitalWrite(13, LOW);
           digitalWrite(12, LOW);
           digitalWrite(11, LOW);
           digitalWrite(10, LOW);
           delay(5000);
        }

Agora basta realizar a chamada da interrupção. Note que o botão que irá gerar a interrupção está ligado na entrada digital 3. Isso não foi por a caso, no Arduíno UNO, somente os pinos 2 e 3 podem gerar uma interrupção. Alem de ligar o periférico na entrada correta do Arduíno na função setup iremos colocar a instrução attachInterrupt() cuja sintaxe é dada por:

                attachInterrupt(digitalPinToInterrupt(pino), ISR, modo);
onde

pino: o número do pino 
ISR: a ISR a ser chamada quando a interrupção ocorre; essa função deve não tomar nenhum parâmetro nem retornar nada. Essa função é chamada de rotina de serviço da interrupção ou ISR (do Inglês, interrupt service routine).
modo: define quando a interrupção deve ser ativada. Quatro constantes estão predefinidas como valores válidos:

         LOW  - acionar a interrupção quando o estado do pino for LOW,
         CHANGE - acionar a interrupção quando o sempre estado do pino mudar
         RISING - acionar a interrupção quando o estado do pino for de LOW para HIGH apenas,
         FALLING - acionar a interrupção quando o estado do pino for de HIGH para LOW apenas.
         HIGH - acionar a interrupção quando o estado do pino for HIGH.

Logo nossa função setup será:

       void setup()
       {
         pinMode(13, OUTPUT);
         pinMode(12, OUTPUT);
         pinMode(11, OUTPUT);
         pinMode(10, OUTPUT);
        attachInterrupt(digitalPinToInterrupt(3),interrupcao,FALLING);
       }

Se quiser ver essa explicação na youtube, clique na figura abaixo:


Melodia com Arduino




Pratique:

Exercício 1. Faça um circuito similar o da figura 2 e ao pressionar o botão, todos os LEDs devem piscar conforme o vídeo do YOUTUBE.


Exercício 2. Faça um circuito similar o da figura 2 e adicione um novo botão que irá tratar um segunda interrupção.  Ao pressionar o botão 1, todos os LEDs devem piscar conforme o vídeo do YOUTUBE e ao pressionar o botão 2 todos os LEDs devem ficar apagados por 5s.






Não esqueça do like do vídeo e de curtir nossa pagina no facebook no link abaixo:

Nenhum comentário:

Postar um comentário