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.

Interrupciones PIC
4.8 (95.91%) 44 vote[s]

Si te sirvió de algo la información de la pagina, podrías invitarme a un café y ayudarme a seguir manteniendo en pie el sitio WEB. Solo cuesta $2USD y me ayudarías enormemente a seguir con mi trabajo. Muchas Gracias por tu visita.




Para Brasil

Se você está em Brasil pode utilizar o botão que está aqui em baixo, para realizar o convite em Reais.




Esta entrada tiene 25 comentarios

  1. 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.

    1. 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!

  2. 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

    1. 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.

  3. 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

    1. 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.

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

  5. 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

    1. 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!

  6. muy buena pagina,fue de mucha ayuda

    1. Que bueno que te gustó!!. Saludos.

  7. 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.

  8. #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

    1. 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.

  9. 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

  10. 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?

    1. 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

  11. 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

    1. 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.

  12. 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

  13. 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?

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

Deja un comentario

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

Interrupciones PIC
8.Interrupciones
Cerrar menú