You are on page 1of 20

Interrupciones

Modos De Activar Las Interrupciones

Ahora que sabes a qu pines se pueden asociar las interrupciones en Arduino, te


falta conocer cmo activarlas, es decir, qu tiene que suceder en ese pin para
que la interrupcin se ejecute. Estos modos de activacin los determinas t
cuando programas la interrupcin y las posibilidades son las siguientes:

LOW: La interrupcin se activa cuando el valor de voltaje del pin elegido es


bajo, esto es, 0V.
CHANGE: La interrupcin se activa cuando el pin cambia de valor, es decir,
cuando pasa de LOW a HIGH o de HIGH a LOW.
RISING: Se activa nicamente cuando el valor del pin pasa de LOW a HIGH.
FALLING: Es el caso opuesto al modo RISING. Se activa la interrupcin
cuando el valor pasa de HIGH a LOW.
HIGH: Este modo solo est disponible en la placa DUE y funciona de
manera opuesta al modo LOW, es decir, se activa cuando el valor de voltaje
del pin es alto.

Cdigo Asociado A Las Interrupciones

Como te he comentado antes, la gracia de las interrupciones reside en que se


ejecuten una serie de lneas de cdigo cada vez que se activa la interrupcin. Para
conseguir esto debers implementar un mdulo asociado a dicha interrupcin.

Seguramente ya conozcas el concepto de mdulo pero por si tienes alguna duda


de a lo que me estoy refiriendo te dir que, bsicamente, se trata de un segmento
de cdigo que se ejecuta cuando es invocado. El void setup(){} y el void loop(){} a
los que seguro que ests acostumbrado son un tipo particular de mdulo. Puesto
que no es el objetivo de este post, no voy a explicarte en profundidad las
caractersticas de los mdulos pero puedes dejar tu comentario si tienes alguna
duda.

Para que puedas asociar un mdulo a una interrupcin correctamente, ste debe
cumplir unas caractersticas concretas:

No puede tener parmetros de entrada, es decir, no puede ser una funcin


del tipo void f_interrupt (int entrada).
No puede devolver ningn valor, por tanto debe ser un mdulo de tipo
void.
Para que este segmento de cdigo pueda interactuar con el resto de tu
programa puedes crear una variable de tipo voltil (por ejemplo volatile int
variable), lo que te permitir leer el valor de dicha variable fuera del mdulo
asociado a la interrupcin y actuar en consecuencia. Algunas de las
prcticas ms habituales consisten en crear una variable que cambia de
estado (entre LOW y HIGH) cada vez que se activa la interrupcin o un
acumulador, una variable que incrementa su valor con cada interrupcin y
que puede ser consultada en cualquier momento por el resto de mdulos.

Ejemplo Del Uso De Interrupciones En Arduino

Ya conoces todas las caractersticas que debes tener en cuenta a la hora de


implementar una interrupcin. Estoy seguro de que podras hacerlo sin problemas.
Aun as, aqu tienes un ejemplo de cmo se crea una interrupcin en Arduino.

Supn que quieres encender un LED o cualquier otro dispositivo mediante el uso
de interrupciones (recuerda que en el caso del LED debes aadirle una
resistencia, puedes leer ms sobre la configuracin de LEDs en este post), de tal
manera que cada vez que se presione un pulsador, ste se encienda.

Una vez configurado un circuito para tu pulsador como el que puedes ver,
conectado al pin correspondiente de interrupcin que prefieras (en este caso el pin
2, es decir, la interrupcin 0), debes elegir el modo en el que se activar dicha
interrupcin. Aunque quizs a primera vista pienses que el modo que debes elegir
es LOW, recuerda que en ese estado la funcin se estara ejecutando mientras
tuvieses presionado el pulsador. Para evitar esto, debes seleccionar el modo
RISING o el FALLING segn prefieras que tu LED se encienda al presionar o
levantar el pulsador.

Aqu te dejo el cdigo para que veas cmo se hara.

/* EducaChip Cmo Usar Las Interrupciones En Arduino*/


// www.educachip.com

//Se declara una variable asociada al pin en el que se va a


conectar
//el LED. Se puede utilizar el valor 13 para observar el
efecto de
//este cdigo a travs del LED de la placa de Arduino.
int LED = 8;

//Se declara una variable voltil que cambiar de estado en


el
//mdulo de la interrupcin y se utilizar fuera.
//Si la variable no se utilizase fuera del mdulo de la
interrupcin
//no sera necesario crearla de tipo voltil.
volatile int estado_actual = LOW;

//Se crea la funcin que se ejecutar cada vez que se active


la
//interrupcin. Esta funcin es de tipo void (por lo que no
devuelve
//ningn valor) y no tiene parmetros de entrada.
void fun_cambio_estado()
{
//Se cambia al estado contrario al actual, es decir, de LOW
se pasa
//a HIGH y de HIGH a LOW.
estado_actual = !estado_actual;
}

void setup()
{
//Se declara el pin digital correspondiente al LED como
salida.
pinMode(LED, OUTPUT);

//Se determina la interrupcin 0 (por lo que el pin


asociado al pulsador
//ser el 2 en caso de tratarse de un Arduino UNO o
similar) a la que se
//le asocia la funcin fun_cambio_estado que se activar al
presionar el
//pulsador (por tratarse del modo FALLING).
attachInterrupt(0, fun_cambio_estado, FALLING);
}

void loop()
{
//Se escribe el valor actual del LED.
digitalWrite(LED, estado_actual);
}

Usando las interrupciones


Para utilizar las interrupciones, en primer lugar tenemos que declarar qu interrupcin
queremos utilizar, en nuestro caso utilizaremos la interrupcin 0, que est en el pin
nmero dos, por lo que declaramos:

1 int interrupcion = 0;

Ahora, en setup, tenemos que especificar qu funcin se llamar en caso de que se


produzca la interrupcin. Para ello, utilizamos la funcin attachInterrupt, que tiene la
siguiente sintaxis:

1 attachInterrupt(interrupt, ISR, mode);

Los argumentos de la funcin attachInterrupt son:


1. Interrupt: Nmero de interrupcin, es decir, en que pin se escuchar para esperar la
interrupcin.
2. ISR: funcin que se llamar en caso de que se produzca la interrupcin.
3. Mode: Define la forma en que se lanzar la ISR , es decir, que tiene que pasar para que se
ejecute la interrupcin. Los diferentes modos son:
LOW: se ejecuta siempre que el valor en el pin sea 0.
CHANGE: se ejecuta siempre que se produzca un cambio.
RISING: se ejecuta mientras el valor va de 0 a 1 (o de 0 a 5 Voltios).
FALLING: se ejecuta mientras el valor va de 1 a 0 (o de 5 a 0 Voltios).
Hay que tener en cuenta que los modos tenemos que escribirlos con letras maysculas, si
no se producir un error.

En nuestro caso, utilizamos:

1 attachInterrupt(interrupcion, funcionInterrupcion, FALLING);

que detectar cundo dejamos de pulsar el botn.

Por otra parte, tenemos que definir la funcin a la que se llamar al detectarse la
interrupcin. En este caso, hemos llamado a la funcin funcionInterrupcin, y la definimos
con el mismo nombre que hemos puesto en attachInterrupt. La funcin entonces es:

1 void funcionInterrupcion(){

2 Serial.print("Interrupt numero ");

3 Serial.println(numInterrupt);

4 numInterrupt++;

5}

Donde imprimimos por el monitor serie el nmero de veces que se ha entrado en la


interrupcin.

Una de las peculiaridades de las interrupciones es que no pueden tener ningn


argumento en su definicin ni devolver ningn valor, por lo que para asegurar que la ISR
tenga un buen acceso a las variables, tenemos que utilizar una variable de tipo volatile, en
este caso de tipo int. Si quieres conocer ms sobre volatile, puedes visitar esta pgina de
referencia.
Otra de las restricciones de las interrupciones es que, mientras que estemos dentro de
una ISR, el resto de interrupciones no sern detectadas, no funcionar delay ni se
actualizar el valor de millis, por lo que es importante que las ISR sean lo ms cortas
posible.

El cdigo
Aqu podis ver el cdigo completo. Recordad que tambin podis descargar el cdigo
junto con las imgenes utilizadas al final de esta entrada.

1 int interrupcion = 0;

2 // Interrupt.0 se encuentra en el pin digital 2

3 // Interrupt.1 se encuentra en el pin digital 3

5 /* Creamos la variable con el calificador volatile

6 para asegurar que la variable ser accesible desde el

7 flujo normal del programa y desde la interrupcion.

8 */

10 volatile int numInterrupt = 0;

11

12 void setup() {

13

14 Serial.begin(9600);

15

16 // Sintaxis interrupciones:

17 // attachInterrupt(numero_interrupt,funcin_a_ejecutar,modo);

18 // Modos LOW,CHANGE,RISING,FALLING

19
20 attachInterrupt(interrupcion, funcionInterrupcion, FALLING);

21 }

22

23 void loop() {

24

25 /*Simulamos una tarea que requiera tiempo.

26 Utilizamos While(true) ya que siempre se cumplir la

27 condicin y nunca dejar de ejecutar el cdigo incluido.

28 */

29 while(true){

30 Serial.print(".");

31 delay(250);

32 }

33 }

34

35 void funcionInterrupcion() {

36 Serial.print("Interrupt numero ");

37 Serial.println(numInterrupt);

38 numInterrupt++; // Aumentamos el nmero almacenado en numInterrupt en una unidad.

39 }

En primer lugar, declaramos las variables que vamos a utilizar, en este


caso interrupcion, con la que indicaremos al microprocesador qu interrupcin queremos
utilizar, y despus numInterrupt, que mostrar el nmero de veces que se ha accedido a la
interrupcin.
En la funcin setup iniciamos el puerto serie y declaramos la interrupcin que vamos a
utilizar con attachInterrupt();.
En la funcin loop, se simula una tarea que requiera cierto tiempo para ejecutarse, en este
caso, para no sobrecargar la visualizacin de la salida del programa por el puerto serie, se
imprime un punto, ., en el puerto serie. Cuando se accede a la interrupcin, al soltar el
pulsador en nuestro caso, se para la ejecucin del programa y se imprime por el puerto
serie Interrupt numero seguido del nmero de veces que se ha accedido a la
interrupcin.
Para poder utilizar interrupciones con Arduino no necesitamos incorporar
ningn tipo de librera a nuestro programa. nicamente necesitamos hacer
referencias a ciertas funciones o mtodos. Ahora veremos cuales son.

attachInterrupt(pin, ISR, modo)


Esta funcin nos va a permitir definir o configurar uno de los pines como
un puerto de interrupcin. Los tres parmetros que admite son:

pin: debemos llevar especial cuidado con este parmetro. Indica


que pin vamos a utilizar como interrupcin. No debemos pasar el
nmero de pin, debemos pasar el ordinal es decir, si trabajamos con
Arduino UNO tenemos dos pines para interrupciones el 2 y el 3. Si
queremos utilizar el 2 debemos poner un 0 y si queremos utilizar el 3
debemos poner un 1. Esto se resuelve muy fcilmente utilizando otra
funcin, digitalPinToInterrupt(pin), que devuelve el ordinal del pin que
queremos utilizar. En este caso si que debemos pasar su nmero.
Por ejemplo, en el caso anterior, si queremos utilizar el pin 2
llamaramos a la funcin digitalPinToInterrupt(2). Esto nos devolver
un 0 y es el mtodo recomendado por Arduino para pasar este
parmetro.
ISR: es una abreviatura de Interrupt Service Routine y no es ms que
la funcin o mtodo que se llama cuando se produce la interrupcin.
Es de un tipo particular ya que no admite parmetros y tampoco
devuelve ningn valor.
modo: define cuando debe ser disparada la interrupcin. Puede tomar
cuatro valores constantes dependiendo de lo que queramos hacer:
LOW: se lanzar la interrupcin cuando el pin est en estado
bajo.
CHANGE: se lanzar la interrupcin cuando el pin cambie de
valor de alto a bajo, o de bajo a alto.
RISING: se lanzar la interrupcin cuando el pin cambie de
estado de bajo a alto.
FALLING: se lanzar la interrupcin cuando el pin cambie de
estado de alto a bajo.

Existe un quinto estado que solo los Arduino Due, Zero


y MKR1000 permiten:

HIGH: se lanzar la interrupcin cuando el pin est en estado


alto.

detachInterrupt(pin)
Si attachInterrupt() nos permite configurar un pin como interrupcin, el
mtodo detachInterrupt() anula esa configuracin. Como parmetro le
pasamos el pin y lo podemos hacer con la
funcin digitalPinToInterrupt(nmero de pin) que nos devolver el ordinal
del pin del que queremos anular la configuracin.
Programacin de interrupciones externas
Dependiendo de la tarjeta Arduino que se vaya a trabajar, existen 2 o
ms pines que responden a cambios externos, asociados a
interrupciones. Para el Arduino UNO son:

INT0: En el puerto D2.

INT1: En el puerto D3.


Para habilitar una interrupcin se debe hacer uso de la
funcin attachInterrupt(), cuya sintaxis es:
//Recomendada:

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);

//No recomendada:

attachInterrupt(interrupt, ISR, mode);

Los parmetros a utilizar en esta funcin son:

Interrupt: es el nmero de la interrupcin. Se puede especificar directamente


con 0 o 1, aunque es ms recomendado usar la
instruccin digitalPinToInterrupt(pin), especificando el pin fsico donde se
encuentra la interrupcin (2 o 3).
ISR: La rutina a llamar (Interrupt Service Routine), cuando la interrupcin
ocurra. Es importante entender que no es posible enviar o recibir parmetros
de estas rutinas. Normalmente se hace uso de variables globales declaradas
como volatile, las cuales se modifican dentro de la rutina y se pueden acceder
una vez se termina la interrupcin.

Mode: Define cul es el tipo de cambio a detectar en el pin. Puede ser LOW
(detecta el pin en estado bajo), CHANGE (detecta un cambio en el estado del
pin), RISING (detecta flancos de subida) y FALLING (detecta flancos de
bajada).
En el caso de querer deshabilitar una interrupcin previamente habilitada,
se puede usar la funcin detachInterrupt(), cuya sintaxis es:
//recomendada

detachInterrupt(digitalPinToInterrupt(pin));

//no recomendada

detachInterrupt(interrupt);

Finalmente, en el caso de necesitar deshabilitar globalmente las


interrupciones (en casos especiales o porciones de cdigo crticas) se
puede usar noInterrupts(). Se debe tener cuidado, pues al deshabilitar
interrupciones dejarn de funcionar las funciones delay(), millis() e
incluso las comunicaciones por puerto serial. Para habilitarlas
nuevamente se usa la funcin interrupts().

http://picolab.com.co/educacion/2017/03/18/interrupciones-externas-arduino/

Tipos de Interrupciones:

Interrupciones HW o externas: Estas son asncronas a la ejecucin del procesador, es


decir, se pueden producir en cualquier momento independientemente de lo que est
haciendo el CPU en ese momento. Las causas que las producen son externas al
procesador y a menudo suelen estar ligadas con los distintos dispositivos de entrada o
salida.
Interrupciones SW: Las interrupciones por software son aquellas generadas por un
programa en ejecucin. Para generarlas, existen distintas instrucciones en el cdigo
mquina que permiten al programador producir una interrupcin. Arduino no soporta
las interrupciones por software
Un evento programado o Timer. Son las interrupciones asociadas a los timers y
gracias a ellas funciona millis().
Excepciones: Son aquellas que se producen de forma sncrona a la ejecucin del
procesador tpicamente causada por una condicin de error en un programa.
Normalmente son causadas al realizarse operaciones no permitidas tales como la
divisin entre 0, el desbordamiento, el acceso a una posicin de memoria no permitida,
etc.
Los vectores de interrupcin es una tabla en memoria que contiene la direccin de
memoria de la primera instruccin de interrupcin. ATmega328p Interrupt vectors,
adems esta tabla establece la prioridad de las interrupciones:

Interrupciones Externas en Arduino

Estas interrupciones hardware, se disearon por la necesidad de reaccionar a suficiente


velocidad en tiempos inimaginablemente cortos a los que la electrnica trabaja habitualmente
y a los que ni siquiera el software era capaz de reaccionar.

Para las interrupciones externas o hardware, solo hay dos pines que las soportan en los
ATmega 328 (p.e. Arduino UNO), son las INT0 y INT1 que estn mapeadas a los pines 2 y 3.
Estas interrupciones se pueden configurar con disparadores en RISING o FALLING para
flancos o en nivel LOW. Los disparadores son interpretados por hardware y la interrupcin es
muy rpida.
El Arduino mega tiene ms pines disponibles para interrupciones externas. Pines de External
Interrupts para Mega: 2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20
(interrupt 3), and 21 (interrupt 2). Estos pines pueden ser configurados para disparar una
interrupcin al detectar un nivel bajo, un flanco ascendente, un flanco descendente o un
cambio de nivel.

En el pin de reset tambin hay otra interrupcin que slo se dispara cuando detecta voltaje
LOW y provoca el reset del microcontrolador.

Para configurar una interrupcin en Arduino se usa la funcin attachInterrupt(). El primer


parmetro a configurar es el nmero de interrupcin, normalmente se usa el n de pin para
traducir al n de interrupcin.

Tabla de pines que soportan interrupcin HW en Arduino:

Board Digital Pins Usable For Interrupts

Uno, Nano, Mini, other 328-based 2, 3

Mega, Mega2560, MegaADK 2, 3, 18, 19, 20, 21

Micro, Leonardo, other 32u4-based 0, 1, 2, 3, 7

Zero all digital pins, except 4

MKR1000 Rev.1 0, 1, 4, 5, 6, 7, 8, 9, A1, A2

Due all digital pins

Esto quiere decir que el Arduino UNO puede definir dos interrupciones hardware llamadas 0 y
1, conectadas a los pines 2 y 3

Para saber qu nmero de interrupcin ests asociada a un pin, debemos usar la


funcin digitalPinToInterrupt(pin). El nmero de interrupcin su mapeo en los pines
depender del MCI. El uso de nmero de interrupcin puede provocar problemas de
compatibilidad cuando el sketch funciona en diferentes placas.

Tabla de interrupciones y nmero de pin asociado:

Board int.0 int.1 int.2 int.3 int.4 int.5

Uno, Ethernet 2 3

Mega2560 2 3 21 20 19 18
32u4 based (e.g Leonardo, Micro) 3 2 0 1 7

Arduino Due tiene grandes capacidades a nivel de interrupciones que permiten asociar una
interrupcin a cada uno de los pines disponibles. Arduino Zero permite asociar una
interrupcin a todos los pines excepto para el pin 4.

Aspectos importantes a tener en cuenta con el uso de interrupciones:

Dentro de la funcin llamada desde la interrupcin, la funcin delay() no funciona y el


valor devuelto por millis() no aumenta. La razn es que estas funciones hacen uso de
interrupciones que no se disparan mientras est disparada una interrupcin externa.
Los datos recibidos por el puerto serie se pueden perder mientras se est en la funcin
llamada por la interrupcin.
Se deben declarar como volatile cualquier variable que sea modificada dentro de la
funcin llamada por una interrupcin: https://www.arduino.cc/en/Reference/Volatile

Tutorial de Interrupciones externas en MCUs AVR de 8 bits: http://www.avr-


tutorials.com/interrupts/The-AVR-8-Bits-Microcontrollers-External-Interrupts

Programacin de interrupciones externas en C: http://www.avr-tutorials.com/interrupts/avr-


external-interrupt-c-programming

Las interrupciones de hardware, tambin conocidas como INT0 e INT1, llaman a una rutina de
servicio de interrupcin cuando algo sucede con uno de los pines asociados. La ventaja es
que Arduino tiene una simple rutina de configuracin para conectar la rutina de servicio de
interrupcin al evento: attachInterrupt (). La desventaja es que slo funciona con dos pines
especficos: pin digital 2 y 3 en la placa Arduino.

El Atmega328p solo tiene dos interrupciones de hardware INT0 e INT1, sin embargo los
microcontroladores AVR pueden tener una interrupcin ante un cambio en cualquier pin, es lo
que denomina pin change interrupt. http://playground.arduino.cc/Code/Interrupts. Estas
interrupciones no son soportadas directamente por Arduino y necesitan ser accedidas a travs
de una librera adicional.

Las interrupciones de cambio de pin pueden habilitarse en ms pines. Para los ATmega
328, pueden habilitarse en cualquiera de los pines de seal disponibles. Estas son disparadas
igual en flancos RISING o FALLING, pero depende del cdigo de la interrupcin configurar el
pin que recibe la interrupcin y determinar qu ha pasado. Las interrupciones de cambio de
pin estn agrupadas en 3 puertos de la MCU, por lo tanto hay 3 vectores de interrupciones
para todo el conjunto de pines. Esto hace el trabajo de resolver la accin en una interrupcin
ms complicada.
Si necesita ms pines para interrupciones, hay un mecanismo para generar una interrupcin
cuando se cambia cualquier pin en uno de los puertos de 8 bits. No sabes pin, sino slo en
qu puerto. Si se genera una interrupcin cuando se cambia uno de los pines ADC0 a ADC5
(utilizado como entrada digital). En ese caso, se llama a la rutina de servicio de interrupcin
ISR (PCINT1_vect). En la rutina se puede averiguar cul de los pines especficos dentro de
ese puerto ha sido el que ha cambiado.

En primer lugar, los indicadores de habilitacin de interrupcin de cambio de pin deben


ajustarse en el registro PCICR. Estos son los bits PCIE0, PCIE1 y PCIE2 para los grupos de
pines PCINT7..0, PCINT14..8 y PCINT23..16 respectivamente. Los pines individuales se
pueden activar o deshabilitar en los registros PCMSK0, PCMSK1 y PCMSK2. En el circuito
Arduino, en combinacin con la hoja de datos Atmel Atmega328, se puede ver que el pin
PCINT0 corresponde al pin 0 en el puerto B (llamado PB0). Este es el pin 8 en el Arduino Uno.
Otro ejemplo es el pin A0 de la tarjeta Arduino, que puede utilizarse como una entrada digital:

Pin Change Interrupt Request 0 (pins D8 to D13) (PCINT0_vect)


Pin Change Interrupt Request 1 (pins A0 to A5) (PCINT1_vect)
Pin Change Interrupt Request 2 (pins D0 to D7) (PCINT2_vect)
Registros para las interrupciones externas y pin change son:

External Interrupt Control Register A: The External Interrupt Control Register A


contains control bits for interrupt sense control.
Name:EICRA
External Interrupt Mask Register: When addressing I/O Registers as data space using
LD and ST instructions, the provided offset must be used. When using the I/O specific
commands IN and OUT, the offset is reduced by 0x20, resulting in an I/O address
offset within 0x00 0x3F.
Name: EIMSK
External Interrupt Flag Register: When addressing I/O Registers as data space using
LD and ST instructions, the provided offset must be used. When using the I/O specific
commands IN and OUT, the offset is reduced by 0x20, resulting in an I/O address
offset within 0x00 0x3F.
Name: EIFR
Pin Change Interrupt Control Register
Name: PCICR
Pin Change Interrupt Flag Register: When addressing I/O Registers as data space
using LD and ST instructions, the provided offset must be used. When using the I/O
specific commands IN and OUT, the offset is reduced by 0x20, resulting in an I/O
address offset within 0x00 0x3F.
Name: PCIFR
Pin Change Mask Register 2
Name:PCMSK2
Pin Change Mask Register 1
Name: PCMSK1
Pin Change Mask Register 0
Name:PCMSK0
Cada interrupcin est asociada con dos bits, un bit de indicador de interrupcin (flag) y un bit
habilitado de interrupcin (enabled). Estos bits se encuentran en los registros de E/S
asociados con la interrupcin especfica:

El bit de indicador de interrupcin se establece siempre que se produce el evento de


interrupcin, independientemente de que la interrupcin est o no habilitada.
Registro EIFR
El bit activado por interrupcin se utiliza para activar o desactivar una interrupcin
especfica. Bsicamente se le dice al microcontrolador si debe o no responder a la
interrupcin si se dispara. Registro EIMSK
1 - Activar interrupciones de cambio de clavijas

Las interrupciones de cambio de clavijas se activan estableciendo ciertos bits en el


registro PCICR como se ve a continuacin. El bit 0 activa el puerto B (PCINT0 -
PCINT7), el bit 1 enciende el puerto C (PCINT8 - PCINT14) y el bit 2 en el puerto
D (PCINT16 - PCINT23). Este cdigo muestra cmo activarlos o
desactivarlos. Tenga en cuenta que estoy usando | = en lugar de = porque es ms
verstil, pero cualquiera funcionara. Tambin puede utilizar decimal o hexadecimal
en lugar de binario, pero creo que el binario es el ms fcil de entender.


PCICR |= 0b00000001; // turn on port b
PCICR |= 0b00000010; // turn on port c
PCICR |= 0b00000100; // turn on port d
PCICR |= 0b00000111; // turn on all ports

2 - Elija qu pasadores interrumpir


S que dije antes que un cambio en cualquiera de los pines en un puerto que
desencadenar el ISR del puerto, pero eso es cierto slo cuando se activa ese pin en
particular. Esto est abajo con lo que se llama una mscara. Puesto que el
ATMEGA328 tiene 3 puertos, tambin tiene tres mscaras: PCMSK0, PCMSK1, y
PCMSK2. stos se fijan de la misma manera que el registro para el PCICR fue
fijado. Una vez ms, puede utilizar | = o simplemente = pero | = le da la posibilidad
de separarlos en diferentes lneas si lo desea.

PCMSK0 |= 0b00000001; // turn on pin PB0, which is PCINT0,
physical pin 14
PCMSK1 |= 0b00010000; // turn on pin PC4, which is PCINT12,
physical pin 27
PCMSK2 |= 0b10000001; // turn on pins PD0 & PD7, PCINT16 &
PCINT23

3 - Escribir el ISR
El ltimo paso es escribir el ISR que se llamar para cada una de estas
interrupciones. Las directrices generales sobre los ISR son hacerlos lo ms cortos
posible y no utilizar retrasos en ellos. Adems, debe deletrearlos y capitalizarlos
correctamente (ver aqu ). Por ltimo, si se utilizan variables en estos ISR, se desea
que la variable sea voltil; Esto le dice al compilador que podra cambiar en
cualquier momento y volver a cargarlo cada vez en lugar de optimizarlo. Para
definir estos ISR simplemente escriba la funcin debajo de su bucle.

ISR(PCINT0_vect){} // Port B, PCINT0 - PCINT7


ISR(PCINT1_vect){} // Port C, PCINT8 - PCINT14
ISR(PCINT2_vect){} // Port D, PCINT16 - PCINT23

Las interrupciones externas (INT0 e INT1) de Arduino pueden ejecutarse porque la


seal de entrada de un pin:

Est en nivel bajo (tiene el valor de 0) LOW


Ha cambiado de estado (tanto para flanco de subida como de bajada) CHANGE
Cambia a nivel alto (flanco de subida) RISING
Cambia a nivel bajo (flanco de bajada) FALLING
DDRD = (1<<PD2); // Configura el pin 2 de PORTD como salida.
PORTD = (1<<PD2); // El pin 2 de PORTD tiene ahora un valor lgico 1.

La operacin << es un operador binario que desplaza hacia la izquierda el nmero de


posiciones especificadas.

Para leer el estado de un botn:

DDRD = 0b11111101; //Configura pin 1 de PORTD como entrada y el resto salida


char my_var = 0; //Variable para guardar la informacin leda en PORTD
my_var = (PIND & (1<<PD1)); /* Le el pin 1 de PORTD y lo coloca en la variable. */

You might also like