VI. Interrupciones en un microcontrolador
Las interrupciones de hardware. Consisten en el cambio en
la secuencia de ejecución de un
programa, esto cuando se da un determinado evento de hardware, para pasar a ejecutar una rutina asociada con el evento
de hardware implicado, a ésta frecuentemente
se le denomina “rutina de servicio”. Una
vez que concluye la ejecución de la rutina
de servicio, el microcontrolador deberá retornar a la secuencia de ejecución que fue interrumpida. Para un determinado MCU, eventos de hardware podrán ser
entre otros: que el puerto serie asíncrono
haya recibido un byte y éste esté listo para ser leído, que se dé un flanco de bajada en un determinado bit de
puerto, etc. En esta exposición, a los
diversos eventos de hardware que pueden hacer que se dé una interrupción, se les denominará como INSTANCIAS DE
INTERRUPCIÓN y cuando éstas llegan a
presentarse, se dice que se tiene un REQUERIMIENTO REQUERIMIENTO INTERRUPCIÓN (RI). N (RI).
Las interrupciones con Arduino nos permitirán reaccionar
a eventos externos a la placa de una forma rápida. Cuando se detecta una señal,
una interrupción, interrumpe el proceso que se está ejecutando. Esto nos va a
permitir dos cosas. Por un lado, ejecutar rápidamente un trozo de código, y por
otro lado parar la ejecución del código que se estaba ejecutando.
Por qué utilizar interrupciones con Arduino
Utilizar interrupciones nos permitirá olvidarnos de
controlar ciertos pines. Esto muy importante ya que, dentro de una aplicación o
programa, no vamos a hacer una única cosa. Por ejemplo, queremos que un LED se
encienda o se apague cuando pulsamos un botón. Esto es relativamente sencillo,
pero cuando además queremos que otro LED parpadee, la cosa se complica.
Las interrupciones no son simplemente para
cambiar y hacer algo diferente. Por ejemplo, estamos montando en bicicleta
llegamos a casa y guardamos la bici en el garaje o un botón es pulsado por el
usuario y permite parar el DFRobot. En estos dos casos
no interrumpimos una acción, pasamos a hacer algo diferente. Terminamos de
hacer una cosa y hacemos otra. En el caso del botón, lo máximo que podemos
hacer es recordar el estado de botón pulsado. Debemos utilizar las
interrupciones para lo que son, interrumpir lo que se está ejecutando y
realizar otra tarea, para luego volver al mismo sitio donde lo habíamos dejado.
Dentro de la gama de interrupciones con
Arduino están las interrupciones
programadas y las interrupciones externas. La filosofía es la
misma, poder ejecutar un código cuando sucede un evento concreto. En el caso de
las interrupciones programadas, el evento se disparará cada cierto intervalo de
tiempo que debemos de configurar. Este tipo de interrupciones no es el objeto
de este artículo. Si quieres saber más puedes ver la referencia de la
librería TimerOne que se encarga de
configurar y gestionar este tipo de interrupciones.
attachInterrupt(pin, ISR, modo)
Esta
función nos va a permitir definir o configurar uno de los pines como un puerto
de interrupción. Los tres parámetros que admite son:
·
pin:
debemos llevar especial cuidado con este parámetro. Indica que pin vamos a
utilizar como interrupción. No debemos pasar el número 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 fácilmente
utilizando otra función, digitalPinToInterrupt(pin), que devuelve el
ordinal del pin que queremos utilizar. En este caso sí que debemos pasar su
número. Por ejemplo, en el caso anterior, si queremos utilizar el pin 2
llamaríamos a la función digitalPinToInterrupt(2). Esto nos devolverá un 0
y es el método recomendado por Arduino para pasar este parámetro.
·
ISR: es una
abreviatura de Interrupt Service Routine y no es más que la función o método
que se llama cuando se produce la interrupción. Es de un tipo particular ya que
no admite parámetros y tampoco devuelve ningún valor.
·
modo:
define cuando debe ser disparada la interrupción. Puede tomar cuatro valores
constantes dependiendo de lo que queramos hacer:
·
LOW: se
lanzará la interrupción cuando el pin esté en estado bajo.
·
CHANGE: se
lanzará la interrupción cuando el pin cambie de valor de alto a bajo, o de bajo
a alto.
·
RISING: se lanzará
la interrupción cuando el pin cambie de estado de bajo a alto.
·
FALLING: se
lanzará la interrupción 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 interrupción cuando el pin esté en estado alto.
detachInterrupt(pin)
Si attachInterrupt()
nos permite configurar un pin como interrupción, el método detachInterrupt()
anula esa configuración. Como parámetro le pasamos el pin y lo podemos hacer
con la función digitalPinToInterrupt(número de pin) que nos devolverá
el ordinal del pin del que queremos anular la configuración.
Ejemplo 1
Circuito eléctrico
Vamos a necesitar el siguiente
material:
·
2 LEDs verdes
·
3 LEDs rojos
·
5 resistencias de 470 Ω
·
2 pulsadores
·
1 resistencia de 1 kΩ
·
Arduino UNO
·
Protoboard
·
Cables macho/macho
Cada pulsador irá conectado a un
pin y tendrán una resistencia pull-down. Esto hará que, en estado normal, sin
pulsar, el pin tengamos un estado bajo. Cuando el pulsador se active tendremos
un estado alto. Por lo tanto, debemos de detectar un cambio de estado de bajo a
alto (RISING).
Por otro lado, los LEDs van a
hacer una secuencia de encenderse y apagarse de izquierda a derecha y de
derecha a izquierda. Simula las luces del coche fantástico. Empezaremos con una
velocidad y según vayamos pulsando los pulsadores se irá aumentando o disminuyendo
la velocidad.
El esquema eléctrico es el
siguiente.
Programación
del sketch de interrupciones con Arduino
La primera parte es la declaración de
contantes y variables. En este punto hay que hacer una aclaración. Cuando
trabajamos con interrupciones con Arduino, hay que llevar especial cuidado
con los métodos ISR que se van a ejecutar cuando se produce el evento.
En general, debemos hacer métodos o funciones
ISR lo más cortas y rápidas posibles. Se puede producir un bloqueo entre los
diferentes ISR. Lo que sucede en estos casos es que solo se ejecuta una a la
vez quedando en cola el resto de interrupciones.
Dentro de las interrupciones no funciona
el delay() (retardo)
por lo tanto no lo utilices. Recuerda que se trata de ejecutar un código lo más
rápido posible. Si quieres hacer que el proceso se pare dentro de un ISR
utiliza la función delayMicrosends(),
ya que funciona con normalidad.
Las variables que vayamos a utilizar tanto
dentro de los métodos ISR como fuera, ya sea en el loop() o en cualquier
otra función, debemos declararlas como volatile. Esta palabra reservada le
dice al compilador que estas variables pueden cambiar de valor en cualquier
momento y, por lo tanto, el compilador debe volver a cargar la variable cada
vez que se hace referencia en algún sitio a ella. Al contrario que ocurre con
otras variables donde el compilador confía en alguna copia que pueda tener en
algún registro del procesador.
Código en Arduino
Simulación en fritzing
Simulación
en proteus
Ejemplo
2
En este ejemplo, se utiliza el pin2 de la tarjeta Arduino
UNO, el cual está asociado a la interrupción INT0 (ver tablas 12.1 y 12.3);
también, se emplea la función attachInterrupt(num int, rutina interrupción,
CHANGE) donde se ha seleccionado la constante CHANGE para indicar cambios de
niveles de voltaje (LOW y HIGH), esta es la forma para detectar o activar la
interrupción . Al pin 2 debe conectarse el pin 13, el cual conmuta esos niveles
de voltaje.
Código en Arduino
Ejemplo 3
Se utiliza el pin 2 (INT0)
para generar la solicitud de interrupción, la forma de activarla es por cambios
de voltajes 0 y 5 V para Arduino UNO o 3.3 V para otros modelos (LOW y HIGH).
Para eso se emplea un puerto digital programado como salida, por ejemplo, el
pin 13, el cual está conectado al pin 2. El cuadro de código Arduino 12.2
contiene la descripción del sketch cap12 funciones. La subrutina de servicio de
interrupción ISR se denomina rutina interruptcion(); en esta función se realiza
la conmutación de pulsos del pin 13 → pin 2, el incremento del tiempo tk y la
función y = sen(t) (las demás funciones el usuario las puede pro- gramar).
Código en Arduino
Código en matlab
Simulación grafica
Ejemplo 4
Para trabajar en tiempo real
es necesario generar una base de tiempo a través de un timer interno o reloj
externo, tal que en forma periódica establezca una señal de interrupción, con
la frecuencia de muestreo adecuada de tal forma que el tiempo empleado en
realizar todas las operaciones dentro de la IRS sean menor al período de
muestreo (la frecuencia de muestreo es el inverso del período de muestreo).
Código Arduino
Código matlab
Simulación grafica
Ejemplo 5
ejemplos en adquisición de datos y control, cuya base de
tiempo es de 2 mseg como período de muestreo, el cual se genera a partir del
TIMER 1 de la tarjeta Arduino UNO.
Código Arduino
codigo matlab
Simulación grafica
Ejemplo 6
La rutina de servicio de
interrupción ISR contiene la implementación discreta del sistema, así como la
ley de control u(tk) para obtener la convergencia del estado del sistema al
estado deseado xd = 1, conforme el tiempo discreto tk evoluciona.
Código Arduino
Código matlab
Simulación graficaEjemplo 7
Encender y apagar,
consecutivamente, un LED en la patilla RB7 cuando se produzca un cambio de
nivel en la patilla RBO Componentes: ISIS: PIC16F876, RES, LED-GREEN y
SW-SPDT-MOM.
Simulación en proteus
Programación en pic
Ejemplo 8
Generar una señal cuadrada de
1KHz utilizando la interrupción del TIMER0 Componentes ISIS: PIC16F876 e
Instrumentos ISIS: OSCILLOSCOPE y COUNTER TIMER.
Programación en pic
Simulación en proteus
Ejemplo 9
Generar una función que permita realizar retardos de 1 segundo empleando
el TIMER1. Componentes ISIS: PIC16F876.
Simulación en proteus
Programación en pic
Ejemplo 10
: Medir el ancho de un pulso mediante el TIMER1 y la interrupción
externa por RBO f figura 18). Componentes ISIS: PIC16F876 y LM016L.
Instrumentos: OSCILLOSCOPE y Generadores: PULSE.
Simulación en proteus
Programación en pic
Ejemplo 11
Generar una señal cuadrada de 1 KHz utilizando la interrupción del
TIMER2. Componentes ISIS: P1CI6F876 e Instrumentos ISIS: OSCILLOSCOPE 1/
COUNTER TIMER.
Simulación en proteus
Programación en pic
Ejemplo 12
Introducir los datos, a través del teclado, de la velocidad de un motor
de corriente continua y generar una señal modulada en un ancho de pulso
proporcional al dato de velocidad. Controlar la velocidad en rpm y visualizarla
en un LCD (figura 24). Componentes ISIS: P1CI8FS76, KEYPAD-PHONE, RES, 2SK1058,
CELL, LM016L y M OTORENCODER.
Programación en pic
Simulación en proteus
Ejemplo 13
Según la duración de pulsación
de un botón obtener tres tipos defunciones: una pulsación corta da lugar a tina
función (por ejemplo, encender un led en el puerto A), una prim era pulsación
mayor de tres segundos da lugar a otra función (por ejem plo encender un led en
el puerto C) y una segunda pulsación mayor de tres segundos de lugar a otra
función (por ejem plo apagar el led del puerto C). Cuando se trabaje con la
segunda o tercera función no se atenderán las pulsaciones cortas. Componentes
ISIS: PIC18F877, BUTTON, RES, LED-RED, LED-BLUE.
Simulación en proteus
Programación en pic
Comentarios
Publicar un comentario