Início
/
Projetos Arduino
/
Projetos Squids
/
Básico
/
Projeto 82 - Como realizar interrupção externa utilizando registradores do Arduino
Projeto 82 - Como realizar interrupção externa utilizando registradores do Arduino
Angelo Luis Ferreira | 14/05/2020
Acessos: 11.606
Básico - Projeto 82
Interrupção externa utilizando registradores de portas do Arduino
Objetivo
Neste projeto vamos mostrar como utilizar registradores de portas DDR e PORT para realizar interrupções externas no Arduino. Vamos, desta forma, exemplificar o conceito de interrupção externa utilizando os registradores DDR, PORT, EIMSK e EICRA para apresentar a técnica mais eficiente para ligar e desligar um componente eletrônico através de um botão ou de um sensor de entrada qualquer (no projeto vamos utilizar um botão e um sensor de toque).
Definições
Vantagens de se utilizar registradores com interrupção externa:
- Maior velocidade de acesso, pois acionaremos a porta diretamente sem a necessidade de funções.
- Otimização de memória do microcontrolador.
- Executar duas tarefas quase que simultaneamente.
Desvantagens de se utilizar registradores com interrupção:
- Código de difícil entendimento.
- Criar códigos utilizando registradores não irão funcionar em todos os tipos e versões do Arduino. Cada microcontrolador possui estruturas de pinos digitais e analógicos diferentes.
- É muito mais fácil causar problemas de funcionamento não intencionais com acesso direto à porta.
Observações:
1. Interrupção externa: É quando o programa do Arduino está instruído para reagir à mudança de um sinal externo, por exemplo, mudança do nível lógico de um sinal gerado por um botão ou por um sensor qualquer (Referência Arduino). Veja o tutorial: Projeto 78 - Como realizar interrupção externa no Arduino usando sensor de toque
1.1. ISR - Interrupt Service Routine ou Rotina de Serviço de Interrupções em português, são instruções que são executadas quando ocorre uma interrupção externa. Entretanto, estas instruções são especiais e possuem algumas limitações, sendo:
. Uma ISR não recebe argumentos e não retorna nada.
. Uma ISR deverá ser a mais curta e rápida possível.
. Se o seu programa utiliza múltiplas ISRs, apenas uma poderá ser executada de cada vez.
. A função delay() não funcionara em uma ISR.
. A função millis() não poderá ser incrementada dentro de uma ISR.
. A função delayMicroseconds() ao não utilizar nenhum contador, funcionará normalmente em uma ISR.
2. O conceito DDR e PORT utilizado neste projeto é específico para Arduino UNO R3 que utiliza o microcontrolador ATmega328. Outros microcontroladores podem ter configurações diferentes. Para saber mais, leia os artigos: Arduino - Manipulação Direta de Portas do blog do Renato Aloi, Port Registers - Documento de Referência Arduino e os projetos: Projeto 81 - Ligar e desligar um led por manipulação direta de portas do Arduino, Projeto 61 - Dado eletrônico com leds e uso de manipulação direta de portas do Arduino e Projeto 60 - Dado eletrônico com Arduino (uso de manipulação direta de portas).
3. O conceito de registradores para interrupções externas EIMSK e EICRA também utilizados no projeto são específicos para o microcontorlado ATmega328, onde utilizamos os pinos INT0 e INT1 (pinos 2 e 3 do Arduino Uno). Para se aprofundar mais sobre a arquetetura do microcontrolador ATmega328 leia: http://www.dca.fee.unicamp.br/~rferrari/EA075_2s2017/Cap.%203.1%20-%20Microcontrolador_ATMega328P.pdf
4. Para avançarmos um pouco mais na utilização de registradores de portas do Arduino, vamos precisar de um conhecimento básico sobre operadores bitwise. Para isso, recomendo que leiam o artigo Operadores Bitwise (Bit-a-Bit) do blog Diogo Matheus.
5. ATENÇÃO: Tome muito cuidado em utilizar o conceito de manipulação direta de portas. Qualquer erro pode danificar permanentemente a sua placa de Arduino.
Registradores de portas do Arduino Uno R3
Registradores de portas (DDR, PORT e PIN) permitem o acesso direto às portas do Arduino. Veja abaixo a imagem que mostra todas portas disponíveis do Arduino UNO:

Nos microcontroladores Arduino Uno, existem 3 canais de portas:
- Porta B (portas digitais de 8 a 13)
- Porta C (entradas analógicas)
- Porta D (portas digitais de 0 a 7)
Para exemplificar melhor vamos utilizar o canal de portas D referente às portas digitais 0 a 7 do Arduino UNO. Microcontroladores de 8bits, como o Arduino UNO por exemplo, cada canal de portas possui 8 bits. Portanto, cada bit representa uma porta (ou pino) de cada canal de portas.

Cada porta do microcontrolador possui 3 registradores, sendo eles:
- DDR que configura o sentido da porta se ela é saída (OUTPUT) ou entrada (INPUT). Substitui a função pinMode().
- PORT que controla se a porta está no estado lógico alto (HIGH) ou baixo (LOW).
- PIN que efetua a leitura das portas configuradas como INPUT pela função pinMode().
No nosso projeto vamos utilizar os registradores DDR e PORT conforme as instruções abaixo:
4.1. Para imprimir o valor 1 em um bit, use sempre o padrão:
DDRporta |= (1 << bit que se pretende configurar como OUTPUT);
PORT |= (1<< bit que se pretende enviar HIGH);
4.1.1. No nosso exemplo, teremos as instruções: DDRD |= (1<<3); e PORTD |= (1<<3)
Obs.: DDRD |= (1<<3); pode ser escrito da seguinte forma: DDRD = DDRD | (1<<3);
4.2. Para imprimir o valor 0 em um bit, use sempre o padrão:
DDR &= ~(1<< bit que se pretende configurar como entrada);
PORT &= ~(1 << bit que se pretende enviar LOW);
DDR (Data Direction Register - read/write)
- No caso do registrador DDR, vamos acrescentar o canal de portas D, ficando portanto como DDRD (portas digitais de 0 a 7 no Arduino Uno).
- Definimos para cada porta se é saída (OUTPUT), usando o 1 ou se é entrada (INPUT), usando o 0.
- A ordem das portas é decrescente e vai de PD7 até PD0 e PB5 até PB0 (desconsidere o erro na imagem, leia PB5 no lugar de PB6)
- Como é um número binário, devemos colocar o modificador "B" na frente, veja o exemplo a seguir:
Ex.:
DDRD = B11111110; // configura portas 1 ate 7 como saídas,e a porta 0 como entrada
Usando operadores bitwise, podemos configurar cada pino individualmente da seguinte forma:
- DDRporta |= (1 << bit que se pretende configurar como OUTPUT); // imprime o valor 1 no bit e configura como saída - defina a Porta B, C ou D e o bit específico.
- DDRporta &= ~(1<< bit que se pretende configurar como INPUT); // imprime o valor 0 no bit e configura como entrada - defina a Porta B, C ou D e o bit específico.
Ex.:
DDRB |= (1<<4); // configura o bit 4 da Porta B como OUTPUT - pino 12 saída
DDRD &= ~(1<<3); // configura o bit 3 da Porta D como INPUT - pino 3 entrada
PORT (Data Register - read/write)
- Como no registrador DDR, vamos acrescentar no PORT o canal de portas D, ficando portanto como PORTD (portas digitais de 0 a 7 do Arduino Uno).
- Definimos para cada porta, se está no estado lógico HIGH, usamos 1 ou se está no estado lógico LOW, usamos 0.
- A ordem das portas vai de PD7 até PD0.
- Como é um número binário, devemos colocar o modificador "B" na frente, veja o exemplo a seguir:
PORTD = B10101000; // registra valor HIGH nas portas digitais 7,5 e 3
Usando operadores bitwise podemos controlar cada pino individualmente, como:
- PORTporta |= (1<< bit que se pretende enviar HIGH); // envia um sinal de alto nível (1) para o bit desejado
- PORTporta &= ~(1 << bit que se pretende enviar LOW); // envia um sinal de baixo nível (0) para o bit desejado
- PORTporta ^= (1 << bit que se pretende enviar HIGH e LOW) // liga e desliga a cada vez que o botão é pressionado. Operador XOR - Referência Arduino.
Ex.:
PORTB |= (1<<4); // envia HIGH para o bit 4 da Porta B - pino 12
PORTB &= ~(1<<4); // envia LOW para o bit 4 da Porta B - pino 12
Registradores para interrupção externa
Para configurarmos um interrupções externas nos projetos com Arduino, podemos utilizar basicamente 2 registradores:
- EIMSK - Habilita INT0 e INT1 do Arduino UNO
- EICRA - Define como INT0 e INT1 são ativadas (LOW, RISING, FALLING ou CHANGE)
EIMSK (External Interrupt Mask Register)
- EIMSK |= (1< // habilita a interrupção externa INT0 no pino 2 Arduino
- EIMSK |= (1< // habilita a interrupção externa INT0 no pino 3 Arduino
Atenção: Necessário que a interrupção global também esteja ativa
Funções para habilitar e desabilitar interrupções globalmente
- sei(); // função que habilita as interrupções externas globalmente
- cli(); // função que desabilita as interrupções externas globalmente
EICRA (External Interrupt Control Register A)
EICRA INT0 (pino 2)
- EICRA |= (0< // configura interrupção externa int 0 - CHANGE
- EICRA |= (1< // configura interrupção externa int 0 - FALLING
- EICRA |= (1< // configura interrupção externa int 0 - RISING
EICRA INT1 (pino 3)
- EICRA |= (0< // configura interrupção externa int 1 - CHANGE
- EICRA |= (1< // configura interrupção externa int 1 - FALLING
- EICRA |= (1< // configura interrupção externa int 1 - RISING
Rotina de Serviço de Interrupções (ISR)
- ISR (INT0_vect) { ... } // define a rotina para quando ocorre interrupção no INT0
- ISR (INT1_vect) {... } // define a rotina para quando ocorre interrupção no INT0
Aplicação
Para fins didáticos e projetos exigem a utilização de códigos profissionais.
Componentes necessários
Referência
|
Componente
|
Quantidade
|
Imagem
|
Observação
|
Protoboard |
Protoboard 830 pontos |
1 |
 |
No mínimo utilizar protoboard com 400 pontos
|
Jumpers |
Kit cabos ligação macho / macho |
1 |
 |
|
Sensor de toque capacitivo |
Sensor touch TP223B |
1 |

|
Tensão de Operação: 2 a 5V
Saída estado Alto (HIGH): 0,8V
Saída estado Baixo (LOW): 0,3V
Tempo de resposta: 220ms (LOW) e 60ms (HIGH)
(datasheet)
|
Led Difuso 5mm |
LEDs 5mm |
1 |
 |
1 LED alto brilho ou difuso de qualquer cor
Você poderá utilizar também LEDs de 3 mm na cor que desejar.
|
Resistor |
Resistor
|
1 |
 |
1 Resistor de 150Ω ou superior
Se precisar usar outros valores, calcule o resistor apropriado para o led utilizado
|
Push Button |
Push button 6X6X5mm |
1 |
 |
|
Capacitor Cerâmico |
Capacitor Cerâmico 2nF a 10nF |
1 |
 |
O capacitor será utilizado para estabilizar a função do botão (push button) no caso de se utilizar interrupção externa
|
Arduino UNO R3 |
Arduino UNO |
1 |
 |
Você poderá utilizar uma placa Arduino UNO original ou similar
|
Montagem do Circuito
Conecte os componentes no Protoboard como mostra a figura abaixo. Verifique cuidadosamente os cabos de ligação antes de ligar seu Arduino. Lembre-se que o Arduino deve estar totalmente desconectado da força enquanto você monta o circuito.
