Saltar al contenido
Control Automático Educación

Interrupciones PIC

Bienvenidos Controleros y Controleras, en esta entrada vamos a aprender a usar las interrupciones con PIC para desarrollar diferentes proyectos. Veremos algunos ejemplos como la detección de Interrupción Externa PIC, interrupcion por Flanco PIC y veremos como hacer un medidor de velocidad de un motor con PIC.

Interrupciones PIC

Con las interrupciones en un microcontrolador vamos a poder hacer que el dispositivo pare de repente la tarea que está realizando para que haga o realice una función con urgencia y después continúe haciendo su rutina habitual.

Por ejemplo. cuando hacemos el llamado de funciones desde el main, lo que se hace es que el programa ejecute un subprograma y luego regrese al programa principal, sin embargo el programador esta definiendo en que momento debe saltar a ejecutar la función mediante las instrucciones, por esta razón se considera sincronas.

Las interrupciones PIC son desviaciones de flujo de control del programa originadas asincrónicamente por diversos sucesos que no dependen del programador, es decir, ocurren en cualquier momento.

Las interrupciones PIC ocurren por sucesos externos como la generación de una interrupción por flanco PIC, una interrupción externa PIC cambiando el nivel en un PIN del microcontrolador o eventos internos tales como el desbordamiento de un contador, terminación del conversor análogo a digital, entre otras.

Interripciones PIC

El comportamiento del microcontrolador ante la interrupción es similar al procedimiento que se sigue al llamar una función desde el programa principal. En ambos casos se detiene la ejecución del programa en curso, se guarda la dirección a donde debe retornar cuando termine de ejecutar la interrupción, atiende o ejecuta el programa correspondiente a la interrupción y luego continua ejecutando el programa principal, desde donde lo dejo cuando fue interrumpido.

Tipos de Interrupciones PIC

Aqui nombramos 10 diferentes causas que producen una interrupción PIC, por lo tanto el primer paso de la rutina de interrupción será identificar la causa de la interrupción.

  • Interrupción externa PIC 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

Interrupciones PIC en CCS

Vamos a ver como podemos utilizar las interrupciones en un PIC utilizando el PIC C Compiler CCS. Lo que veremos aqui puedes aplicarlo en cualquier microcontrolador de Microchip, por ejemplo esto sirve para las interrupciones PIC 18F4550 CCS, Interrupciones PIC 16F877A, Interrupciones PIC 16F84 o cualquier otro. A modo de ejemplo lo mostraremos como usar las interrupciones PIC en el 18F887.

Los pasos que se deben seguir para atender una interrupción, son los siguientes

  • Digitar la función correspondiente a la interrupción. La función debe comenzar con # y la interrupción correspondiente, por ejemplo para la función de interrupción por RB0 se digita #int_EXT
  •  En el programa principal, habilitar las interrupciones en forma global, con la instrucción: enable_interrupts(GLOBAL);
  •  En el programa principal, habilitar la interrupción correspondiente, como ejemplo se muestra como habilitar la interrupción externa por RB0: enable_interrupts(INT_EXT);

Existen diferentes tipos de interrupción en el microcontrolador, algunas de ellas se mencionan a continuación:
#INT_EXT              INTERRUPCIÓN EXTERNA
#INT_RTCC            DESBORDAMIENTO DEL TIMER0(RTCC)
#INT_RB                  CAMBIO EN UNO DE LOS PINES B4,B5,B6,B7
#INT_AD                  CONVERSOR A/D
#INT_EEPROM   ESCRITURA EN LA EEPROM COMPLETADA
#INT_TIMER1      DESBORDAMIENTO DEL TIMER1
#INT_TIMER2     DESBORDAMIENTO DEL TIMER2

Aqui de dejo un Documento con todas las interrupciones del PIC usando PIC C Compiler 👉 Interrupciones PIC

Interrupción Externa PIC 16F887 – PIC 16F877A – PIC 18F4550

Hacer un programa que me incremente un contador de 0 a 9, cuando ocurra una interrupción externa por RB0. Cuando el contador llegue a 9, comienza de nuevo en cero. (El código de implementación se encuentra al final del post)

Interrupciones con PIC

 

Vemos el video donde el código de implementación de la interrupcion externa PIC 16F887, sin embargo el código sirve para la interrupcion PIC 18F4550, el PIC 16F877A o cualquier otro PIC.

Interrupción por Flanco de Subida y Flanco de Bajada

En algunos casos, puede interesarnos leer unicamente los flancos de subida o los flancos de bajada de algún tren de pulsos que esté entrando al microcontrolador como lo vemos en la siguiente imagen

Flancos de Subida y Bajada

Este tipo de señales es bastante común en sensores como encoders los cuales son muy utilizados para medir posición o velocidad angular.

Encoder

Para configurar la lectura de la  INTERRUPCIÓN POR FLANCO DE SUBIDA en el Compilador CCS C Compiler debemos utilizar el siguiente comando:

Para configurar la lectura del INTERRUPCIÓN POR FLANCO DE BAJADA en el Compilador CCS C Compiler debemos utilizar el siguiente comando:

Medidor de Velocidad de un Motor DC con PIC

Si dominas este ejemplo, estarás en la capacidad de hacer un control de velocidad de un motor DC con PIC, dado que uno de los factores más importantes en este tipo de aplicaciones es poder realizar un medidor de RPM con PIC 16F877A, 16F887, 18F4550 o cualquier otro PIC.

Vamos a realizar un medidor de Velocidad de un Motor DC con PIC, utilizando como sensor un Encoder de 10 Pulsos por Revolución. Para eso vamos a necesitar configurar el MOTOR-ENCODER del proteus dando doble click y colocando los 10 pulsos. Este ejemplo es una adaptación del ejemplo visto en la entrada de PWM, si todavia no has estudiado el PWM te recomiendo primero veas esa entrada (click aqui para ir a la entrada) y luego regreses aqui para hacer la práctica del medidor de Velocidad.

A través de un potenciometro, regularemos la velocidad del motor 12VDC, utilizando un mosfet en la etapa de potencia. El motor tiene acoplado un Encoder que entrega un tren de pulsos. Ese tren de pulsos debe ser conectado en el PIN RB0 del PIC y por medio de la interrupción Externa y por lectura bien sea del flanco de subida o flanco de Bajada, se debe calcular la velocidad en RPM (Revoluciones por Minuto) y mostrarlas en una pantalla LCD. (El código de implementación se encuentra al final del post)

Velocidad de un Motor DC con PIC y Encoder

El diagrama esquemático del sensor de velocidad RPM de un Motor DC con Microcontrolador PIC es:

Código de Implementación:

A continuación se presenta el Código de Implementación de los dos ejemplos de vistos en esta entrada con relación a las interrupciones externas por RB0. Recuerda que para ver el código, solo basta con compartir la información de este post con alguno de los siguientes tres botones.

Código – Interrución Externa CCS

Pueden descargar el código y el diseño en proteus aqui:

>>>>>8. Interrupciones<<<<<<<<

Si desean utilizar la interrupción externa PIC 18F4550 o cualquier otro de la familia 18, debes cambiar el encabezado por:

Si desean utilizar la interrupción externa PIC 16F877A o cualquier otro de la familia 16, debes cambiar el encabezado por:

Código – Medidor de Velocidad de un Motor con PIC

Click aqui para descargar los archivos del medidor de velocidad del motor DC

>>>>Velocidad del Motor DC <<<<<<<<<

Ayuda compartiendo la información de la pagina en redes sociales, dale un like, twittea o un plus (+) en google, para que mas personas puedan acceder a la información del sitio web.

Eso es todo por la entrada del dia de hoy, espero les haya gustado y hayan aprendido algo nuevo. Si te ha servido el contenido de esta entrada, de los videos y los códigos de implementación y deseas apoyar mi trabajo invitandome a un café super barato, puedes hacerlo en el siguiente link:

👉 Invitar a Sergio a un Café ☕️

Que esten muy bien, nos vemos en la siguiente entrada.

Entradas relacionadas

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Comentarios (25)

Hola estoy tratando de hacer un protector por falta de fase trifasico con pic16f876 y tengo problemas para comparar el valor RMS con el seteo de dos potenciometros Umax y Umin para discriminar falla por baja tension o sobretension, ademas quisiera hacer todo por soft y se me hace muy largo el programa , quisiera tambien agregarle deteccion de falla de fase o desfasaje asi como seteo de retardo de sensibilidad y proteccion por sobretemperatura, uso una fuente capacitiva en la misma placa y la entrada de las 3 fases es por rectificacion de media onda atenuada y filtrada, llegue a posisionarme dentro de los parametros del pic pero haciendo simulaciones con proteus no consigo que la s condicionales se cumplan correctamente y no entiendo por que razon, no uso interrupciones solo un lazo infinito y otro para la toma de 100 muestras con un clock de 4Mhz interno, la finalidad es tener la menor cantidad de componentes externos posible asi como reducir el espacio ocupado por el protector, esta claro que para la falta de fase solo se sensan 2 de ellas ya que la tercera al usarla como entrada de alimentacion ,si falta o falla por baja tension , el sistema queda desconectado ademas de apagado, he visto protectores similares con pic16f785 pero su velocidad no es buena y suelen fallar los relays de salida por inestabilidad en el sensado, quisiera saber si el uso de interrupciones me ayudaria a solucionar algo o complicaria mas el software, muchas gracias por tanta informacion , prometo co mi palabra que si este proyecto llega a funcionar te envio toda la documentacion para que sea publicado y asi poder aportar algo a tu obra, espero poder en algun momento.

Responder

Hola Ariel. Bueno tu proyecto requiere de paciencia para conseguirlo hacer funcionar. Primero si deseas hacer todo por software, talvez en lugar de usar potenciometros, podrías definir el umbral min y max dentro del programa y ajustarlo para cada protector, si usas potenciometros entonces te recomiendo usar trimmers. Para la detección de fallas estas detectando directamente con el PIC la caida de la fase a través de una retificación? El uso de Interrupciones no debería complicar tu programa, ellas podrían ayudarte a que el PIC pare de hacer lo que este haciendo en el ciclo infinito y atienda una tarea prioritaria, por ejemplo la caída de una fase, para desenergizar el sistema. Saludos!

Responder

hola, con el tema del motor con encoder como seria para la construccion fisica del diagrama?? porque por lo que vi no vienen motores asi con encoder incorporados

Responder

Hola Nicolas, en el mercado SI venden motores con el encoder incorporado. Claro que también puedes colocar tu encoder directamente en el eje del motor y usar un circuito optico para capturar los pulsos del motor.

Responder

hola ,excelente tu manera de enseñar,te pido un favor para un proyecto ¿como hago pwm con 2 botones uno + y otro – ,no logro hacer el programa

Responder

Has visto la entrada de PWM? Con eso colocas los dos botones y haces un contador que será tu duty cicle. Con el boton + aumentas el contador el cual ira a la función set_pwm1(contador); y con el boton – lo decrementas y listo. El como usar botones y contadores, lo puedes ver en la entrada de display 7 segmentos por ejemplo. Saludos.

Responder

hola soy nuevo aayudeme, como hago para grabar el programa al pic tengo el pickit3

Responder

Empieza el curso desde el comienzo, Da click aqui para ver el curso Gratis de Microcontroladores PIC, en la tercera entrada se explica como usar el PicKit3

Responder

Hola Sergio C, me gustabti explicación, sin embargo eso de las interrupciones conozco poco, por ello te pregunto ¿cómo hacer que una función ponga la hora en tiempo real (cada milesima de segundo ) en una parte de la pantalla mientras corre mi programa?
De antemano michas gracias Sergio

Responder

Si quieres poner la hora, te recomiendo mejor que le adiciones al PIC un reloj calendario de tiempo real (DS1307) comunicado con I2C, aqui te dejo la entrada donde se explica como configurar ese reloj y como usarlo. Comunicación I2C con PIC (click aqui). Exitos!

Responder

muy buena pagina,fue de mucha ayuda

Responder

Que bueno que te gustó!!. Saludos.

Responder

hola, al usar el INT_RB no logro conseguir que me lea las interrupciones por otro pin, me insiste en solo usar el RB0, ¿podria regalarme otro ejemplo usando otro pin porfa?.
por cierto muy buen blog.

Responder

#INT_EXT
ext_isr()
{
contador++;
}
en esta parte me genera un error
warning 208 funtion not void and does not return a value ext_isr
cuando coloco void ext_isr se soluciona pero no estoy seguro de que sea la solucion correcta, agradeceria su respuesta

Responder

No es un error, es simplemente una advertencia. Tu solución es correcta, dado que esa función no retorna nada para evitar la advertencia basta colocar el void.

Responder

muy buen video y explicacion amigo me sirvio de mucho, pero quisiera saber como se realizaria pero para que me marcara las revoluciones en 3 display si pudiears ayudarme seria de mucha ayuda

Responder

Es tomar los datos de las revoluciones y en lugar de mandarlos al lcd los mostramos en los displays multiplexando cada uno de estos de la forma como se ve en esta entrada: https://controlautomaticoeducacion.com/microcontroladores-pic/multiplexaje-de-display/

Responder

Hola es muy bueno tu sitio y estoy aprendiendo mucho. Estoy tratande de hacer interrupciones por cambio de estado en los puertos b4-b7 y no funciona. Lei que debo usar ANSE y ANSEH pero el compilador me dice que no estan inicializados y ya no encuentro manera de hacer eso y nadie ha hecho nada en la red acerca del tema. Me podrias ayudar?

Responder

Albert es similar al ejemplo que hemos visto acá en el post. Puedes inicialmente hacer el Ejemplo 1 por interrupción por los pines b4-b7, es solo cambiar #INT_EXT por #INT_RB y activar las interrupciones antes de entrar al ciclo infinito

saludos

Responder

hola, muy interesante lo que compartes , tengo una duda de como implementar lo siguiente, quiero hacer un corrimiento de un led en una hilera de 5 leds con un retardo de 1000ms , al momento de leer el adc del pic poner como condicion que cuando lea un valor de 3V se detenga la secuecia y deje prendido el led justo donde iba, ojala puedas darme una idea ya he implementado el adc y la manera para obtener de 0 a 5 v con un potenciometro pero no me sale la parte que menciono. saludos

Responder

Bueno como vimos en el ejemplo del ADC aca en el blog (click aca) suponiendo que lees el voltaje y lo guardas en una variable tipo long llamada bits (lectura a 10bits), vas a preguntar cuando llegue a 3 voltios (614 bits) y dejas estatico. algo asi como:

PORTB=0B00000001; //Prendo unicamente el led de RB0
while(1){
set_adc_channel(0); //Selecciono el canal 0 (RA0)
delay_ms(1); //llamo retardo de 1 ms
bits=read_adc();
if(0b100000)
PORTB=0B00000001; //Prendo unicamente el led de RB0
if(bits>614){ //Si es mayor a 3 V desplace los leds
PORTB=PORTB<<1;
DELAY_MS(1000);
}
}

Mas o menos asi, si el voltaje es mayor a 3 quedesplace los leds. Ya si solo necesitas los 3 voltios exactos, va ser muy complicado que consigas esa exactitud. Igual te digo que NO porbé ese codigo, es mas o menos lo que se me vino a la mente. Saludos.

Responder

BUENAS DISCULPE NECESITO SABER COMO USAR EL DISPLAY DE 7 SEGMENTOS DE 2 DIGITOS, COMO LO PROGRAMARIA PARA QUE ME SALGAN LOS NUMEROS 10,11,12 ….
Y COMO HARIA PARA HACER QUE DECRECIERA EL NUMERO OSEA NECESITO ESTO MISMO PERO QUE SUBA Y QUE BAJE

Responder

Hola. Puedes dar un vistazo al post donde hablo de multiplexación de display:
https://controlautomaticoeducacion.com/multiplexaje-de-display/

Responder

que tal me agrada tu blog, me a ayudado bastante, tengo una dudo, se puede usar en el mismo programa tanto las interrpuciones por rb4-rb7 como por rb0?

Responder

Hola jose Maria. Claro que si. Puedes usar ambas interrupciones. Saludos

Responder