Como encender y apagar un LED utilizando interrupciones con CCS.

Interrupción Externa rb0

Como están amigos, hoy les traemos el post : ” Como encender y apagar un LED utilizando interrupciones con CCS ” y es que el manejo de este recurso será una herramienta importantísima a la hora de realizar nuestros proyectos electrónicos con microcontroladores.

Definir una interrupción desde el punto de vista teórico no es nada complicado. vemos a continuación:

Interrupciones definición:

Para explicarlo de forma sencilla imagina que en el momento en que estoy escribiendo este post me suena el celular ring ring ring , entonces debo abandonar mi teclado para atender la llamada, converso, cuelgo y luego retomo la escritura de mi POST en el mismo lugar en donde lo deje.

Esto es lo mismo que sucede en un microcontrolador al ocurrir una interrupción, el PIC detiene lo que esta haciendo para atender otro requerimiento señalado por la interrupción lo termina y retoma lo que dejo de hacer en el mismo punto en donde lo dejo.

Este funcionamiento basado en interrupciones le da a los microcontroladores un gran potencial para el desarrollo de proyectos de mediana y gran complejidad.

Ahora para profundizar un poco en el tema, dependiendo del tipo de micro controlador, pueden existir muchas y muy diversas fuentes o casusas de interrupciones.

Veamos en el caso de nuestro querido y viejo PIC16f628 encontramos que puede manejar los siguientes tipos de interrupciones:

Fuentes de interrupción en el PIC16f628A

Las fuentes de interrupción del PIC16f628 son 4 , fuentes se denomina a todo aquello que puede generar una interrupción dentro del PIC.

  1. Cambio de nivel en el PIN RB0/INT.
  2. Desbordamiento del Timer0.
  3. Cambio de estado de una de los 4 pines de más peso (RB7:RB4) del puerto B.
  4. Finalización de la escritura en la EEPROM de datos.

Las interrupciones no vienen activadas por defecto en el microcontrolador, para poder utilizarlas debemos editar el registro INTCON que esta ubicado en la posición 0BH del banco 0 de los registros de funciones especiales del PIC.

En la actualidad gracias a que contamos con programas compiladores de alto nivel como el CCS bastan unos cuantos sencillos comandos para activar y desactivar interrupciones, pero siempre es bueno saber como se hace esto a la vieja usanza en ASSEMBLER.

Activar o desactivar Interrupciones en el PIC16F628A.

Para realizar esta tarea en lenguaje ensamblador debemos echar mano al registro INTCON, haciendo un pequeño paréntesis imagina que este registro es como un DIPSWITCH en el cual hay que activar o desactivar las opciones que necesitamos.

Siendo los 5 bits de mayor peso los que controlan :

GIE: (Global Interrupt Enable), Bit que activa o desactiva todas las interrupciones.
1: Habilita todas las interrupciones.
0: Deshabilita todas las interrupciones
PEEIE: (EEPROM Interrupt Enable), Activa la Interrupción por fin de escritura en la EEPROM
1: Habilita la interrupción cuando termina la escritura de la EEPROM.
0: Deshabilita esta interrupción
TOIE: (TMR0 Overflow Interrupt Enable), Controla la interrupción por desborde del TMR0
1: Habilita interrupción por desborde del TMR0
0: Deshabilita esta interrupción
INTE: (Interrupt Enable RB0/INT), Controla la interrupción por activación del pin RB0/INT
1: Habilita la interrupción al activarse RB0/INT
0: Deshabilita esta interrupción.

RBIE: (RB Port Change Interrupt Enable), Controla la interrupción por cambio de estado en RB7:RB4
1: Habilita esta interrupción
0: Deshabilita esta interrupción

Por Ejemplo si quisiéramos activar la interrupción por cambio de estado del pin RB0/INT deberíamos escribir la siguiente instrucción:

movlw b’10010000’
movwf INTCON

Pero como ya habíamos dicho antes gracias al uso de compiladores como el CCS podemos hacerlo de una manera mas sencilla e intuitiva de la siguiente manera:

ENABLE_INTERRUPTS(GLOBAL);         // HABILITA LA INTERRUPCION 
CLEAR_INTERRUPT(INT_EXT);          // LIMPIA LA INTERRUPCION 
ENABLE_INTERRUPTS(INT_EXT);        // HABILITA LA INTERRUPCION EXTERNA 
ext_int_edge( H_TO_L );            // DEFINE QUE ES POR FLANCO DE BAJADA 

Cuando y por que utilizar interrupciones ?.

Esta pregunta es 100% valida ya que el inicio puede que la idea de utilizar interrupciones no sea muy clara.

Esto puede deberse a que en la mayoría de los casos comenzamos acostumbrándonos a programar utilizando la sentencia IF para revisar el cambio de estado por ejemplo de algún PIN configurado como entrada o el cambio de una variable utilizada como bandera.

El problema con el uso de los IF para revisar los cambios de estado de los pines o el cambio de estado de alguna variable es que se debe esperar a que el PIC termine de realizar todas las rutinas que están en la pila del programa hasta llegar al punto de la sentencia IF.

Allí radica la diferencia, pues una interrupción no espera a que el PIC termine de ejecutar ninguna rutina para que se le atienda. La interrupción obliga al PIC a dejar TODO lo que esta haciendo para atender la interrupción y en términos de eficiencia este procedimiento no tiene comparación.

Ahora se debe tener claro que las tareas contenidas dentro de las interrupciones deben ser muy precisas y especificas. Una regla de oro es por ejemplo evitar los retardos o DELAYS dentro de las interrupciones.

Esto con la finalidad de que el PIC salga lo antes posible de la interrupción y continúe ejecutando sus tareas de rutina.

Dejemos ahora la teoría y vayamos a ver dos casos prácticos:

Encender y apagar un LED utilizando la interrupción externa del PIN RB0.

Este es un programa muy sencillo pero nos servirá para analizar como funciona una interrupción externa.

El circuito tendrá 2 leds, el primero un led verde D1 conectado el PIN RB7 que parpadea debido a una rutina de cambio de estado del pin con un delay alojado en el programa principal.

El segundo led un led amarillo D2, conectado a RB6 el cual cambiara de estado dependiendo de un pulsador conectado al pin de interrupción externa RB0.

Veamos el programa:

#include <16f628.h>
#fuses NOMCLR,NOWDT
#use delay (clock=4000000)
#use fast_io(B)

//////////////////////////// - LA RUTINA DE INTERRUPCION - ///////////////////////
#INT_EXT              
void interrumpe()
{
output_toggle(PIN_B6);       // CAMBIA EL ESTADO DEL PIN B6 LED AMARILLO
}

//////////////////////////- PROGRAMA PRINCIPAL-///////////////////////////////////
void main (void)
{
set_tris_b(0x01);           // El pin RBO de la interrupción seteado como INPUT /
output_b(0x00);

/////////////////////////// COMANDOS DE LA INTERRUPCION ///////////////////////////
ENABLE_INTERRUPTS(GLOBAL);         // HABILITA LA INTERRUPCION ////////////////////
ENABLE_INTERRUPTS(INT_EXT);        // HABILITA LA INTERRUPCION EXTERNA ////////////
ext_int_edge( H_TO_L );            // DEFINE QUE ES POR FLANCO DE BAJADA //////////

////////////////////////- RUTINA DE PARPADEO LED VERDE ////////////////////////////
while (1)

{
output_HIGH(PIN_B7);
delay_ms(200);
output_low(PIN_B7);
delay_ms(200);
}

}

El circuito en PROTEUS:

Interrupción externa rb0 pic16f628

Al ejecutar el programa el LED verde conectado a RB7 parpadea de forma continua, mientras que el led amarillo solo cambiara de estado al presionar el pulsador conectado al pin de la interrupción EXTERNA RB0.

Como puedes ver no existe ningún IF en el programa, ya que la interrupción externa no la necesita.

Encender y apagar un LED utilizando la interrupción del TIMER 1

Veamos a continuación un ejemplo de como hacer parpadear un led cada medio segundo utilizando ahora para ello la interrupción del TIMER 1.

Debo puntualizar que la interrupción del TIMER1 no se encuentra en el registro INTCON sino en el registro T1CON del PIC ubicado en la dirección 10H.

Pero no te preocupes de todo esto se encarga el compilador.

Aunque esta interrupción posee el mismo principio de funcionamiento que la interrupción externa que vimos anteriormente nos da la ventaja de configurar el periodo de tiempo en que se ejecutara cada ciclo de interrupción, y eso por su puesto es muy útil para proyectos por ejemplo de relojes, alarmas o temporizadores.

En este caso la interrupción del TIMER1 esta programada para ocurrir cada medio segundo debido a la configuración del PRESCALER fijado en 8 y la precarga del TIMER con el valor 3036.

Los detalles de la configuración del TIMER0 lo puedes revisar en este POST :

COMO CONFIGURAR EL TIMER 1 DEL PIC.

Veamos a continuación el código de nuestro programa:

#INCLUDE <16f628a.h>
#fuses NOWDT,NOPROTECT,NOLVP,NOLVP,NOMCLR 
#USE fast_io(B) 
#USE delay (clock=4000000,INTERNAL)

//---------------------- INTERRUPCION DEL TIMER 1 ----------//
#int_TIMER1
void temp1s(void)
{
OUTPUT_TOGGLE(PIN_B6);           // CADA MEDIO SEGUNDO SE CAMBIA EL ESTADO DEL LED AMARILLO.
set_timer1 (3036);               // SE RECARGA EL TIMER CON EL VALOR 3036
}

//-------------------------- PROGRAMA PRINCIPAL ----------------------//
void main (void)

{

//--------------------------- SETEO DE LA INTERRUPCION DEL TIMER 1 ------//

enable_interrupts (global);                   // Se habilitan las interrupciones
enable_interrupts (INT_TIMER1);               // Se habilita la interrupción del TIMER 1
setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 );   // Se configura el prescaler a 8
set_timer1 (3036);                            // Se precarga el TIMER con el valor 3036

SET_TRIS_B(0x00);                             // Se configura el puerto B como salida

output_b(0x00);
//-------------------------- RUTINA DE PARPADEO DEL LED VERDE ------------//

while(1)
{
output_HIGH(PIN_B7);
delay_ms(200);
output_low(PIN_B7);
delay_ms(200);
}
}

El programa al igual que el ejemplo anterior ejecuta una rutina de parpadeo de el LED verde cada 200 milisegundos.

Mientras que la interrupción del TIMER1 hace parpadear el led amarillo cada 1/2 segundo gracias a la configuración hecha en el TIMER.

El circuito es el mismo que el anterior solo que esta vez vamos a eliminar el pulsador ya que su tarea la realizara ahora el TIMER1 por medio de la interrupción.

Esta seria la simulación en el PROTEUS:

Interrupción timer1 pic16f628

Y como puedes ver en este programa tampoco tenemos ningún IF involucrado en todo el programa. Genial no ?

Eso ha sido todo amigos en este post “Como encender y apagar un LED utilizando interrupciones con CCS” esperamos que nuestro pequeño aporte en algún momento te sea de utilidad.

Recuerda que una manera de ayudarnos o agradecer nuestro trabajo es visitando la publicidad que aparecen a lo largo del post. Gracias!
Recuerda también que puedes visitar todo el contenido de nuestro blog de informática en :

TODOS LOS POSTS DE INFORMATICA.

Tambien puedes visitar nuestro canal de youtube en :

CANAL DE YOUTUBE TECNOCIENCIA

Agregue un comentario

Su dirección de correo no se hará público. Los campos requeridos están marcados *