Está en la página 1de 7

UNIVERSIDAD NACIONAL DE SAN LUIS

Facultad de Ciencias Físico Matemática y Naturales –Dpto. de Electrónica


Técnico Universitario en Microprocesadores
Ingeniería Electrónica Orientación Sistemas Digitales 2019

PROCESADORES I
LABORATORIO 5: Interrupciones y Timers/Counters en Arduino
“Este Material de basa, en gran parte, al aporte brindado por la Ing. Andrada Tivani Astri Edith, docente de la
cátedra Procesadores II”
1. Objetivos
Los objetivos del presente laboratorio son:
• Interiorizarse con la utilización de interrupciones
• Aprender a utilizar timers/counters
2. Material de Referencia
 Arduino Curso práctico de formación - Óscar Torrente Artero
 Página Web Oficial de Arduino

3. Interrupciones
Conceptos básicos
Las interrupciones son recursos o mecanismos del microcontrolador para responder a eventos, permitiendo
suspender temporalmente el programa principal, para ejecutar una subrutina de servicio de interrupción
(ISR, por sus siglas en inglés, Interrupt Service Routines); una vez terminada dicha rutina, se reanuda la
ejecución del programa principal.
Por ejemplo, para monitorear el estado lógico que posee un pin, se debería leer su valor continuamente.
La acción de monitorear constantemente la ocurrencia de un evento se denomina “polling” (mecanismo de
sondeo continuo, que consiste en que el mismo microcontrolador se encargue de leer el estado o
información del evento). Es una técnica ineficiente por diversos factores:
 Se tiene un continuo consumo del procesador y de energía, al tener que preguntar continuamente
por el estado de la entrada.
 Si la acción necesita ser atendida inmediatamente, por ejemplo en una alerta de colisión, esperar
hasta el punto de programa donde se realiza la consulta puede ser inaceptable.
 Si el pulso es de corta duración, o si el procesador está ocupado haciendo otra tarea mientras se
produce, es posible que no se percate de la ocurrencia del evento producida y nunca se llegue a
verla.
En lugar de utilizar polling, se emplea un dispositivo denominado controlador de interrupciones (también
conocido como unidad de interrupciones), la arquitectura AVR de los microcontroladores que se utilizan las
placas Arduino, incluyen una unidad de interrupciones (ver el diagrama a bloques de la figura 1), para
controlar la solicitud de eventos o dispositivos periféricos.
Controlar la solicitud de interrupciones a través de la unidad de interrupciones evita consumir tiempo del
microcontrolador para sensar o monitorear por sí mismo la información de un evento. La unidad de
interrupciones le da versatilidad al microcontrolador.
Cuando se genera una interrupción, la unidad de interrupciones indica al microcontrolador que un evento
requiere solicitud de interrupción, el microcontrolador consulta los registros de la unidad de interrupciones
para determinar qué tipo de interrupción se está generando. También guarda el estatus del contador de
programa, con el número de interrupción se determina por medio de la tabla de vectores de interrupción con
las direcciones de la memoria flash donde se ubican las rutinas de servicio de interrupción ISR, de esta forma
se puede acceder y ejecutar el correspondiente código de la ISR. Las direcciones donde residen las rutinas de

Laboratorio N° 5 Página 1
UNIVERSIDAD NACIONAL DE SAN LUIS
Facultad de Ciencias Físico Matemática y Naturales –Dpto. de Electrónica
Técnico Universitario en Microprocesadores
Ingeniería Electrónica Orientación Sistemas Digitales 2019

servicio de interrupción ISR (tabla de vectores) se encuentran en las primeras localidades de memoria del
espacio de programa, iniciando en la localidad 0x0000 con la interrupción con mayor prioridad: RESET.

Figura 1 Diagrama a bloques del núcleo de microcontroladores AVR Atmega

En los microcontroladores Atmega hay dos tipos de interrupciones, el primer tipo corresponde a eventos
externos que generan un estado lógico (cambio de voltaje) y también por transición como un pulso
electrónico de disparo (triggered). Se habilita una bandera de interrupción (interrupt flag), dependiendo de la
prioridad de interrupción, el contador del programa (program counter) toma la dirección de memoria de la
tabla de vectores y salta a la localidad de memoria correspondiente donde se encuentra la rutina de la
interrupción solicitada.
De manera automática, por hardware se limpia la bandera de interrupción (interrupt flag); también se puede
limpiar las banderas de interrupción por software, ya que tienen asociados sus respectivos bits de
habilitación en el registro de estado (status register).
El segundo tipo de interrupciones corresponden a las interrupciones que pueden ser cambiadas o
reasignadas por software en los pins del microcontrolador, estas interrupciones no necesariamente tienen
banderas de interrupción.
La forma en que funcionan las interrupciones en los microcontroladores Atmega es por prioridades o
jerarquía.

Rutinas de servicio de interrupción


Las rutinas o subrutinas de servicio de interrupción ISR son funciones que realizan actividades de adquisición
de datos, por ejemplo: lectura de señales analógicas por medio de conversores analógico-digital, sensores

Laboratorio N° 5 Página 2
UNIVERSIDAD NACIONAL DE SAN LUIS
Facultad de Ciencias Físico Matemática y Naturales –Dpto. de Electrónica
Técnico Universitario en Microprocesadores
Ingeniería Electrónica Orientación Sistemas Digitales 2019

digitales (encoders); también llevan a cabo, manipulación y procesamiento de datos, cálculo numérico, envío
de información digital o comandos a través de puertos y convertidores digital analógico.
Generalmente, este tipo de funciones o subrutinas no tienen parámetros o argumentos de entrada y
tampoco retornan datos (salvo casos excepcionales).
Una característica deseable de las ISR es que deben tener el código necesario para llevar a cabo todas las
necesidades de la tarea específica del proceso que atienden; es decir, se requiere que sea tan rápidas como
sea posible. El diseño debe contemplar este objetivo del menor tiempo de ejecución dado que mientras se
esté ejecutando el bucle principal y todo el resto de funciones se encuentran detenidas. Frecuentemente la
función de la ISR se limitará a activar un flag, incrementar un contador, o modificar una variable. Esta
modificación será atendida posteriormente en el hilo principal, cuando sea oportuno.
Cuando el contador del programa atiende una interrupción indica al microcontrolador que suspenda
temporalmente las instrucciones que está ejecutando en ese momento, y transfiera el contador del programa
al tipo de interrupción donde se tiene una ISR con el código específico para llevar a cabo la actividad
solicitada; después de terminar el código del tipo de IRS, el contador del programa retorna al conjunto de
instrucciones que estaba ejecutando en el programa principal. Si más solicitudes de interrupción ocurren
mientras se encuentra en proceso alguna interrupción, permanecerán en espera por orden de prioridad.
Cuando el contador de programa sale de una interrupción, retornara al programa principal y ejecutara una o
más instrucciones antes de atender alguna interrupción pendiente.
El sistema Arduino tiene un conjunto de funciones para manejo de interrupciones, como las que a
continuación se describen.
attachInterrupt(num int, ISR, mode)
Esta función específica la subrutina de servicio de interrupción ISR a ejecutar por el microcontrolador, se
debe indicar el número de interrupción num int; con esta información la función attachInterrupt(...) coloca en
la tabla de vectores (indexada por num int) la dirección de memoria donde reside la subrutina del usuario ISR,
la cual no contiene parámetros o argumentos de entrada y ningún tipo de dato a retornar.
La forma en que se detecta o activa la interrupción se especifica en el argumento mode, pudiendo ser
cualquiera de las siguientes 4 constantes: LOW, CHANGE, RISING y FALLING; tal y como se muestra en la
figura 2.

Figura 2 Argumento MODE

Es importante recalcar que para los microcontroladores Atmega168/328 (modelos Arduino UNO, Nano,
Duemilanove) tienen asociadas las interrupciones INT0 e INT1, mapeadas a los pins 2 y 3, respectivamente.

Laboratorio N° 5 Página 3
UNIVERSIDAD NACIONAL DE SAN LUIS
Facultad de Ciencias Físico Matemática y Naturales –Dpto. de Electrónica
Técnico Universitario en Microprocesadores
Ingeniería Electrónica Orientación Sistemas Digitales 2019

Figura 3 Asignación de pins digitales por interrupción del modelo Arduino UNO.

Dentro de las funciones de servicio de interrupción (añadidas a través de attachInterrupt()), la función


delay() no trabaja. De igual forma para la función millis() el valor que retorna no se incrementará.

detachInterrupt(num int)
Esta función retira la dirección de memoria de la ISR del usuario, por lo que, deshabilita el número de
interrupción de la tabla de vectores proporcionado en el argumento num int.

noInterrupts()
Esta función deshabilita interrupciones. No tiene parámetros de entrada, ni retorna datos.

interrupts()
Re-habilita interrupciones, cuando previamente las interrupciones fueron deshabilitadas con la función
noInterrupts(). Esta función no tiene parámetros o argumentos de entrada, ni retorna datos.

Sugerencias para escribir una ISR


Cuando escriba una rutina de servicio de interrupción (ISR) tome en cuenta los siguientes aspectos claves:
 Mantener el código necesario y depurado dentro de la ISR.
 No usar funciones delay(...).
 No usar funciones Serial.print(...).
 Las variables globales que se compartan con el programa principal y diversas funciones, se
recomienda utilizar el modificador volatile.
 Variables compartidas en diferentes partes del programa.
 Dentro de la ISR no utilizar instrucciones que deshabiliten o activen interrupciones.

Varaibles con modificador volatile


Variables compartidas entre funciones ISR y funciones normales o con el lazo principal loop() deben ser
declaradas usando el modificador volatile para indicarle al compilador que dicha variables podrían cambiar
en cualquier tiempo.
Por lo que, el compilador deberá recargar la variable cuando se le haga referencia.

4. Timers / Counters
Conceptos básicos
Los timers son muy utiles a la hora de temporizar cosas, ya que si se utiliza delay(), se bloquea el Arduino
hasta que transcurra el tiempo indicado, y esto, en la mayoría de los casos es inaceptable.
Los timers permiten disparar interrupciones cuando ha transcurrido un determinado tiempo, es decir, si se
activa un timer para que se dispare a los 3 segundos, la placa Arduino seguirá ejecutando las siguientes líneas
de código y cuando hayan pasado los 3 segundos, la ejecución se detendrá para atender la interrupción,
ejecutando las instrucciones de la ISR.
Existen 2 Modos de funcionamiento para los Timers de Arduino:

Laboratorio N° 5 Página 4
UNIVERSIDAD NACIONAL DE SAN LUIS
Facultad de Ciencias Físico Matemática y Naturales –Dpto. de Electrónica
Técnico Universitario en Microprocesadores
Ingeniería Electrónica Orientación Sistemas Digitales 2019

 PWM – La salidas OCxy se utilizan para generar señales PWM.


 CTC (Clear Timer on Compare match) - Cuando el contador alcanza el valor del registro compare
match, se dispara la interrupción.

Figura 4 Timer en modo comparador

En los chips AVR Atmega 328 (Arduino UNO) se dispone de 3 timers, mientras que en los Atmega 2560
(Arduino MEGA) se cuenta con 6 timers.
 Timer 0: contador de 8 bits (contará como máximo hasta 255). Se utiliza en las funciones delay() y
millis().
 Timer 1: contador de 16 bits (contará como máximo hasta 65535).
 Timer 2: contador de 8 bits. Similar al Timer 0.
 Timer 3, 4 y 5: son tres contadores de 16 bits similares al Timer 1, disponibles en la Arduino MEGA.
Los Arduinos más comunes (UNO, MEGA, Pro Mini) usan un cristal de 16Mhz, (excepto el Pro Mini de 3v usa
de 8Mhz) y en teoría, se podría disparar una interrupción cada 1/16.000.000 segundos, pero no tiene sentido
ya que una sola instrucción necesita varios pulsos, y es por eso que: los timers tienen un registro que indica
cada cuantos ticks de reloj debe dispararse.
Si este contador se disparase cada tick del cristal el máximo tiempo que el contador podría abarcar sería de:

Figura 5 Calculo de demora básica


El ATMEGA328, incluye divisores de la frecuencia básica del cristal de cuarzo, de modo que solo salta un tick
al contador cada ciertos ticks del patrón básico. En Arduino UNO esos divisores pueden ser 1, 8, 64, 256 y
1024. De ese modo, expresado en forma coloquial, se puede “frenar” hasta mil veces la velocidad de
incremento del contador de disparo.
Para tener en cuenta los posibles inconvenientes:
 Existen instrucciones que dependen de los timers, debido a esto pueden dejar de funcionar, o lo
harán de forma indeseada. Entre estos están, los pines PWM y analogWrite() y la librería Servo.
 Si el timer entra en conflicto con algún dispositivo o función, puede ser muy complicado comprender
a simple vista el problema.
 Si la ISR tarda más en ejecutarse de lo que tarda en saltar a la nueva interrupción (por un error de
cálculo), antes de finalizar la ejecución puede volver a ingresar a la ISR, porque ha disparado de
nuevamente el Timer. Esta situación se refleja de inmediato porque Arduino dejará de funcionar y no
suele ser visible esta causa.

Laboratorio N° 5 Página 5
UNIVERSIDAD NACIONAL DE SAN LUIS
Facultad de Ciencias Físico Matemática y Naturales –Dpto. de Electrónica
Técnico Universitario en Microprocesadores
Ingeniería Electrónica Orientación Sistemas Digitales 2019

5. Actividades y Ejercicios

Ejercicio N°1
Teniendo en cuenta este código:
void setup()
{ pinMode(LED_BUILTIN, OUTPUT);
attachInterrupt( 0, ServicioBoton, LOW);
}
void loop()
{
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);

void ServicioBoton()
{ digitalWrite(LED_BUILTIN, HIGH);
}

A. Realice las modificaciones necesarias para que sea estable el tiempo que permanece encendido el
led.
B. Modifique el parámetro MODE y explique por qué el sketch puede realizar la misma tarea aún con
otro diferente al utilizado aquí.
C. Simule en Proteus ISIS

Ejercicio N° 2
Usando la interrupción INT0 de un Arduino UNO realizar el incremento de un contador t como múltiplos de h
= 0.001, es decir:
𝑡 = 𝑡 +ℎ
Exhibir el resultado por medio del LCD Keypad Shield.

Ejercicio N° 3
Realice un sketch en el que con dos botones se realicen incrementos y decrementos de un contador, siendo
la mayor prioridad el decremento en caso de tener presionados ambos botones. Muestre por pantalla la
cuenta y el último botón presionado.
Utilice el LCD Keypad Shield.

Ejercicio N° 4
Realice el encendido y apagado de 3 leds. Dependiendo de los 3 botones del LCD Keypad Shield. Con un
botón implemente una demora de intermitencia de 500 ms. Con otro realice una baliza con los 3 leds,
encendido de a un led en un sentido definido por el alumno, con una demora de 1 segundo (ENCENDIDO –
DEMORA – APAGADO). Finalmente, con el tercer botón, encienda cada par de leds (3 combinaciones) cada 5
segundos con una duración de encendido de 1 segundo.
Se requieren los cálculos de valores.
Incluya muestra de carteles por el LCD, para indicar en qué modo de operación está trabajando.

Ejercicio N° 5
Laboratorio N° 5 Página 6
UNIVERSIDAD NACIONAL DE SAN LUIS
Facultad de Ciencias Físico Matemática y Naturales –Dpto. de Electrónica
Técnico Universitario en Microprocesadores
Ingeniería Electrónica Orientación Sistemas Digitales 2019

Compare el código realizado en el ejercicio 4, para cada demora, con el que puede obtener de las páginas
generadoras de código online para temporizadores Arduino.

Ejercicio N° 6
Explique qué es el efecto rebote que se tiene al presionar un botón y dos formas de disminuirlos (vía harware
y vía software).

Ejercicio Nº 7
¿Qué relación guardan las funciones millis() y delay() entre sí?
¿Qué relación poseen dichas funciones con el Timer0?

Ejercicio N° 8
Realice las demoras del ejercicio 4 por medio de alguna librería para timers de Arduino. Queda a elección del
alumno la misma.

Ejercicio Nº 9
Realice la implementación de la eliminación del efecto rebote por medio de software del ejercicio N° 3.

Laboratorio N° 5 Página 7

También podría gustarte