Una interrupción es un evento que hace que el microcontrolador deje de ejecutar la tarea que está realizando para atender dicho acontecimiento y luego regrese y continue la tarea que estaba realizando antes de que se presentara la interrupción. El pic 16F628 (y el 16F628A) tiene 10 fuentes de interrupción, si las interrupciones están habilitadas cada vez que una de estos acontecimientos se presente el pic dejará de ejecutar el programa para ir a atender la interrupción y al termino de la misma continuará ejecutando el programa donde lo había dejado. Las fuentes de interrupción son:
- Interrupción externa RB0/INT
- Interrupción por cambio lógico en el puerto B (pines RB7 a RB4)
- Interrupción por desborde del timer 0 (TMR0)
- Interrupción por desborde del timer 1 (TMR1)
- Interrupción por comparación exitosa exitosa en TMR2
- Interrupción del comparador
- Interrupción del transmisor del USART
- Interrupción del receptor del USART
- Interrupción del módulo CCP
- Interrupción del EEPROM
Los registros asociados con las interrupciones son el registro de control de interrupcion INTCON, el registro habilitacion de interrupciones de perifericos PIE1 y el registro de interrupciones de perifericos PIR1. En el registro INTCON se encuentra el bit de habilitacion global de interrupciones GIE, el bit de habilitacion de interrupcion por perifericos PEIE y los bits de habilitacion de algunas interrupciones como la interrupcion externa del pin RB0 (INTE), la interrupcion por cambio de estado en los pines RB4 a RB7 (RBIE) y la interrupcion por desborde del timer 0 (T0IE), asi como las banderas correspondientes a cada interrupcion (INTF, RBIF y T0IF). En el registro PIE1 se encuentran los bits de habilitacion de las demas interrupciones y en el registro PIR1 se encuentran las banderas asociadas con cada interrupcion.
Para habilitar las interrupciones se deben seguir los siguientes pasos:
La ventaja de utilizar interrupciones es que mientras se espera a que se presente el evento que produce la interrupción el microcontrolador puede estar ejecutando cualquier otra tarea. De ese modo el micro no esta ciclado en una sola tarea sino que puede seguir trabajando en otras hasta que una interrupción haga que el programa salte y ejecute la tarea que se quiera y al terminarla el programa continuara su ejecución en el punto en el que se encontraba en el momento de presentarse la interrupción.
En el ejemplo pasado se vió como leer botones e interruptores, ahora se va a realizar el mismo programa pero haciendo uso de interrupciones y para que se aprecie que el microcontrolador puede realizar otra tarea mientras se espera la interrupción el programa hará que parpadee el puerto A cada medio segundo. Por lo demas el programa sera igual, tendra 4 botones conectados a los pines RB4 a RB7 y 4 leds conectados a la parte baja del puerto B. Se habilitarán las interrupciones y de ese modo los botones se leerán solamente al ser presionados. Veamos entonces el codigo:
Ese es el código del programa principal. Se comienza declarando el vector de reset y el vector de interrupcion, después se configuran los puertos, el puerto A como salida, la parte baja del puerto B como salida y la parte alta del puerto B como entrada. Hasta ahí lo único nuevo es la declaración del vector de reset. Después se configuran las interrupciones: Primero se habilita el bit RBIE del registro INTCON que es el correspondiente a la interrupción por cambio de estado en los pines RB4 a RB7, después se pone a cero el bit RBIF del mismo registro para poner la bandera de interrupción en cero y así evitar entrar a la rutina de servicio sin que exista una interrupción, y por último se habilita el bit GIE para habilitar las interrupciones. De esta manera la interrupción queda configurada y habilitada. Es muy importante siempre limpiar las banderas de interrupción antes de habilitar el bit GIE.
Después de configurar las interrupciones se pasa al programa principal que lo único que hace es poner a 1 todos los pines del puerto A, esperar medio segundo, poner a 0 todos los pines del puerto A, volver a esperar medio segundo para iniciar de nuevo el ciclo y así el programa se repite una y otra vez. La tarea de encender los leds correspondientes a cada botón queda en manos de la rutina de interrupción:
La rutina es muy parecida a la del programa del ejemplo anterior con algunos cambios pequeños. Lo importante en la rutina es que al entrar a la misma se deshabilitan las interrupciones al poner a 0 el bit GIE, con esto evitamos que se produzca otra interrupción mientras se está atendiendo una. Después de hacer eso el programa simplemente identifica la tecla pulsada y enciende el led correspondiente. Ya que se encendió el led la rutina continua hacia la etiqueta SALIDA_ISR donde primero se limpia la bandera de interrupción poniendo a 0 el bit RBIF y después se vuelve a habilitar la interrupcion poniendo a 1 el bit GIE, ambos del registro INTCON. Para terminar la rutina y regresar al programa principal se utiliza la instrucción retfie (RETurn From IntErruption). La rutina de servicio de interrupción siempre debe terminar con esa instrucción.
Por último una imágen del diseño esquemático de este ejemplo:
Descargar código: Manejo de interrupciones.
Para mayor información sobre el uso y configuración de interrupciones y los registros de configuración consulta las hojas de datos proporcionadas por Microchip: 16f628a, 16f877a.
- Habilitar el bit correspondiente a cada interrupcion.
- Limpiar la bandera correspondiente a la interrupcion habilitada para evitar falsas interrupciones.
- En caso de ser necesario habilitar el bit PEIE del registro INTCON (necesario para todas las interrupciones con excepcion de INTE y RBIE).
- Habilitar el bit de habilitacion global de interrupciones GIE del registro INTCON.
La ventaja de utilizar interrupciones es que mientras se espera a que se presente el evento que produce la interrupción el microcontrolador puede estar ejecutando cualquier otra tarea. De ese modo el micro no esta ciclado en una sola tarea sino que puede seguir trabajando en otras hasta que una interrupción haga que el programa salte y ejecute la tarea que se quiera y al terminarla el programa continuara su ejecución en el punto en el que se encontraba en el momento de presentarse la interrupción.
En el ejemplo pasado se vió como leer botones e interruptores, ahora se va a realizar el mismo programa pero haciendo uso de interrupciones y para que se aprecie que el microcontrolador puede realizar otra tarea mientras se espera la interrupción el programa hará que parpadee el puerto A cada medio segundo. Por lo demas el programa sera igual, tendra 4 botones conectados a los pines RB4 a RB7 y 4 leds conectados a la parte baja del puerto B. Se habilitarán las interrupciones y de ese modo los botones se leerán solamente al ser presionados. Veamos entonces el codigo:
Ese es el código del programa principal. Se comienza declarando el vector de reset y el vector de interrupcion, después se configuran los puertos, el puerto A como salida, la parte baja del puerto B como salida y la parte alta del puerto B como entrada. Hasta ahí lo único nuevo es la declaración del vector de reset. Después se configuran las interrupciones: Primero se habilita el bit RBIE del registro INTCON que es el correspondiente a la interrupción por cambio de estado en los pines RB4 a RB7, después se pone a cero el bit RBIF del mismo registro para poner la bandera de interrupción en cero y así evitar entrar a la rutina de servicio sin que exista una interrupción, y por último se habilita el bit GIE para habilitar las interrupciones. De esta manera la interrupción queda configurada y habilitada. Es muy importante siempre limpiar las banderas de interrupción antes de habilitar el bit GIE.
Después de configurar las interrupciones se pasa al programa principal que lo único que hace es poner a 1 todos los pines del puerto A, esperar medio segundo, poner a 0 todos los pines del puerto A, volver a esperar medio segundo para iniciar de nuevo el ciclo y así el programa se repite una y otra vez. La tarea de encender los leds correspondientes a cada botón queda en manos de la rutina de interrupción:
La rutina es muy parecida a la del programa del ejemplo anterior con algunos cambios pequeños. Lo importante en la rutina es que al entrar a la misma se deshabilitan las interrupciones al poner a 0 el bit GIE, con esto evitamos que se produzca otra interrupción mientras se está atendiendo una. Después de hacer eso el programa simplemente identifica la tecla pulsada y enciende el led correspondiente. Ya que se encendió el led la rutina continua hacia la etiqueta SALIDA_ISR donde primero se limpia la bandera de interrupción poniendo a 0 el bit RBIF y después se vuelve a habilitar la interrupcion poniendo a 1 el bit GIE, ambos del registro INTCON. Para terminar la rutina y regresar al programa principal se utiliza la instrucción retfie (RETurn From IntErruption). La rutina de servicio de interrupción siempre debe terminar con esa instrucción.
Por último una imágen del diseño esquemático de este ejemplo:
Descargar código: Manejo de interrupciones.
Para mayor información sobre el uso y configuración de interrupciones y los registros de configuración consulta las hojas de datos proporcionadas por Microchip: 16f628a, 16f877a.
Me salvaste la vida amigo!! xD bueno, en realidad no tan así, pero el programa me ayudo para sacar algunas dudas ke tenia con una practica de la escuela =D
ResponderEliminarGracias!
saludos..
De nada, que bueno que te fue de utilidad =).
ResponderEliminarhola amigo.
ResponderEliminaruna acotacion deberias subir el archivo ***.DNS y el ***.HEX para poder implementarlode manera mas facil.
saludos y gracias!!
Muchas gracias por darte el tiempo de explicar tan bien!!! Llevaba horas buscando algún ejemplo de interrupciones que me ayudara y nada, hasta que llegue aquí, gracias!!!!
ResponderEliminaroye excelente tu post, solo con una duda, fijate que necesito comparar 5 entradas al pic 16f84a, digamos todo el puerto A, como hago para saber las entradas de todo el puerto A con btfsc es decir cuando el puerto A tenga digamos 00001, que llame a una rutina, cuando sea 10101, llame a otra rutina, es decir comparar todo el puerto, GRACIAS DE ANTEMANO, estoy en eso de un mi proyecto de la U, si pudieras responderme mi correo es yemo_orozco@hotmail.com
ResponderEliminarMuy bueno el Post, el tema de las interrupciones es de obligado aprendizaje.
ResponderEliminarUn saludo.
Excelente contribución mi pana, te felicito ;) Muchísimas gracias de verdad. Saludos.
ResponderEliminarMuy buena información y detallada, pero quien es el autor? necesito darle crédito en mi trabajo de investigación
ResponderEliminarUtiliza nuestro foro de electronica si tienes dudas no relacionadas con este tema.