Tutoriales PIC_ Interrupciones (Conceptos Básicos)

6
24/6/2016 Tutoriales PIC: Interrupciones (conceptos básicos) http://picfernalia.blogspot.com.ar/2012/06/interrupcionesconceptosbasicos.html 1/6 Fundamentos de microcontroladores aplicados a la familia PIC de Microchip. Proyectos y Aplicaciones. Tutoriales PIC Seleccionar idioma Con la tecnología de Traductor de Google VIERNES, 22 DE JUNIO DE 2012 Interrupciones (conceptos básicos) Una interrupción es un aviso provocado por un módulo del PIC, por un cambio en el estado de un pin o un recordatorio de que ha pasado un cierto tiempo. Como su nombre indica este aviso interrumpirá la tarea que se este haciendo en ese momento y pasaremos a ejecutar una rutina de servicio o gestión de la interrupción. Veremos un repaso de los bits y registros de control asociados a las diferentes interrupciones, como habilitarlas y como escribir rutinas de servicio (ISR). Crearemos definiciones (#define) que nos permitirán operar con las interrupciones sin tener que recordar los bits/registros asociados, a la vez que facilitarán la tarea de portar nuestro programa a otro compilador y/o microcontrolador. Es importante familiarizarse con el manejo de interrupciones, ya que nos evita poder manejar muchos tipos de eventos sin estar pendientes de ello. En sucesivos tutoriales veremos como el uso de interrupciones nos permite aprovechar de forma mucho más eficiente los recursos del PIC. Archivos de código asociado a esta entrada: int_defs.h test_int.c Habilitación de interrupciones: Antes de entrar en detalles sobre cada interrupción por separado hemos de describir un par de bits (bits 7 y 6 del SFR INTCON) que tienen un efecto global sobre la activación de bloques de interrupciones. INTCON.GIE > habilita (1) o deshabilita (0) todas las interrupciones. INTCON.PEIE > habilita (1) o deshabilita (0) las interrupciones asociadas a módulos periféricos. Por ejemplo, antes de poder usar la interrupción del temporizador TMR0 debemos asegurarnos de que las interrupciones globales estén habilitadas (INTCON.GIE=1). Si lo que deseamos es usar la interrupción asociada a la recepción del puerto serie, tanto INTCON.GIE como INTCON.PEIE deben estar a 1, ya que dicha interrupción está declarada como periférica. Para usar estos bits de una forma más conveniente incluiríamos los siguientes defines (en el programa principal o bien en un fichero .h incluido en el proyecto): // Global flags (without priority levels) #define enable_global_ints INTCONbits.GIE=1 #define enable_perif_ints INTCONbits.PEIE=1 #define disable_global_ints INTCONbits.GIE=0 #define disable_perif_ints INTCONbits.PEIE=0 Hay varias razones para usar estas (o similares definiciones): Siempre es más facil recordar enable_global_ints que acordarse de que hay que poner a 1 el bit GIE del registro INTCON. Si cambiamos a otro compilador donde la forma de direccionar los bits de los registros es diferente, basta cambiar las definiciones (esto es, usar un fichero .h distinto). En el caso p.e. del compilador MikroC Pro en vez de INTCONbits.GIE usaríamos INTCON.GIE. Si cambiamos a otro controlador, puede que los bits correspondientes cambien de registro y/o nombre. De nuevo, un cambio en el fichero de encabezamiento hace que no sea preciso cambiar el resto del código. Bits asociados a cada interrupción: Además de los bits anteriores que afectan de forma global a las interrupciones, para cada fuente de interrupción hay tres bits asociados: 530,573 PÁGINAS VISTAS EN TOTAL Buscar SEARCH IN THIS BLOG Modulación PWM (Pulse Width Modulation) Conversor ADC Interrupciones (conceptos básicos) Comunicaciones puerto serie (UART) Manejo de motores DC usando PWM LO MÁS VISTO ESTE MES Audio con PWM Brújula electrónica Levitador magnético Medidor de potencia Monitor pulso cardíaco PROYECTOS: 2013 (16) 2012 (13) julio (3) junio (10) Aplicación: Audio con PWM Modulación PWM (Pulse Width Modulation) Decodificador de un mando a distancia Comunicaciones UART con paridad Comunicaciones UART con interrupciones Comunicaciones puerto serie (UART) Uso de temporizadores (timers) Niveles de prioridad en interrupciones Interrupciones (conceptos básicos) Introducción al BLOG ARCHIVO DEL BLOG

description

interrupciones pic

Transcript of Tutoriales PIC_ Interrupciones (Conceptos Básicos)

Page 1: Tutoriales PIC_ Interrupciones (Conceptos Básicos)

24/6/2016 Tutoriales PIC: Interrupciones (conceptos básicos)

http://picfernalia.blogspot.com.ar/2012/06/interrupcionesconceptosbasicos.html 1/6

Fundamentos de microcontroladores aplicados a la familia PIC de Microchip. Proyectos y Aplicaciones.

Tutoriales PIC

Seleccionar idioma

Con la tecnología de Traductor de Google

VIERNES, 22 DE JUNIO DE 2012

Interrupciones (conceptos básicos)

Una interrupción es un aviso provocado por un módulo del PIC, por un cambio en el estado de un pin o unrecordatorio de que ha pasado un cierto tiempo. Como su nombre indica este aviso interrumpirá la tareaque se este haciendo en ese momento y pasaremos a ejecutar una rutina de servicio o gestión de lainterrupción.

Veremos un repaso de los bits y registros de control asociados a las diferentes interrupciones, comohabilitarlas y como escribir rutinas de servicio (ISR). Crearemos definiciones (#define) que nos permitiránoperar con las interrupciones sin tener que recordar los bits/registros asociados, a la vez que facilitarán latarea de portar nuestro programa a otro compilador y/o microcontrolador.

Es importante familiarizarse con el manejo de interrupciones, ya que nos evita poder manejar muchostipos de eventos sin estar pendientes de ello. En sucesivos tutoriales veremos como el uso deinterrupciones nos permite aprovechar de forma mucho más eficiente los recursos del PIC.

Archivos de código asociado a esta entrada: int_defs.h test_int.c

Habilitación de interrupciones:

Antes de entrar en detalles sobre cada interrupción por separado hemos de describir un par de bits (bits 7y 6 del SFR INTCON) que tienen un efecto global sobre la activación de bloques de interrupciones.

INTCON.GIE > habilita (1) o deshabilita (0) todas las interrupciones.INTCON.PEIE > habilita (1) o deshabilita (0) las interrupciones asociadas a módulos periféricos.

Por ejemplo, antes de poder usar la interrupción del temporizador TMR0 debemos asegurarnos de que lasinterrupciones globales estén habilitadas (INTCON.GIE=1). Si lo que deseamos es usar la interrupciónasociada a la recepción del puerto serie, tanto INTCON.GIE como INTCON.PEIE deben estar a 1, ya quedicha interrupción está declarada como periférica.

Para usar estos bits de una forma más conveniente incluiríamos los siguientes defines (en el programaprincipal o bien en un fichero .h incluido en el proyecto):

// Global flags (without priority levels)

#define enable_global_ints INTCONbits.GIE=1

#define enable_perif_ints INTCONbits.PEIE=1

#define disable_global_ints INTCONbits.GIE=0

#define disable_perif_ints INTCONbits.PEIE=0

Hay varias razones para usar estas (o similares definiciones):

Siempre es más facil recordar enable_global_ints que acordarse de que hay que poner a1 el bit GIE del registro INTCON.Si cambiamos a otro compilador donde la forma de direccionar los bits de los registros esdiferente, basta cambiar las definiciones (esto es, usar un fichero .h distinto). En el casop.e. del compilador MikroC Pro en vez de INTCONbits.GIE usaríamos INTCON.GIE.Si cambiamos a otro controlador, puede que los bits correspondientes cambien deregistro y/o nombre. De nuevo, un cambio en el fichero de encabezamiento hace que nosea preciso cambiar el resto del código.

Bits asociados a cada interrupción:

Además de los bits anteriores que afectan de forma global a las interrupciones, para cada fuente deinterrupción hay tres bits asociados:

530,573

PÁGINAS VISTAS EN TOTAL

Buscar

SEARCH IN THIS BLOG

Modulación PWM (PulseWidth Modulation)

Conversor ADC

Interrupciones (conceptosbásicos)

Comunicaciones puertoserie (UART)

Manejo de motores DCusando PWM

LO MÁS VISTO ESTE MES

Audio con PWM

Brújula electrónica

Levitador magnético

Medidor de potencia

Monitor pulso cardíaco

PROYECTOS:

2013 (16)

2012 (13)

julio (3)

junio (10)

Aplicación: Audio conPWM

Modulación PWM (PulseWidth Modulation)

Decodificador de unmando a distancia

Comunicaciones UARTcon paridad

Comunicaciones UARTcon interrupciones

Comunicaciones puertoserie (UART)

Uso de temporizadores(timers)

Niveles de prioridad eninterrupciones

Interrupciones(conceptos básicos)

Introducción al BLOG

ARCHIVO DEL BLOG

Page 2: Tutoriales PIC_ Interrupciones (Conceptos Básicos)

24/6/2016 Tutoriales PIC: Interrupciones (conceptos básicos)

http://picfernalia.blogspot.com.ar/2012/06/interrupcionesconceptosbasicos.html 2/6

IE (interrupt enable): determina si la interrupción está o no habilitada. Si no lo está, aunquela condición de la interrupción se cumpla, la interrupción no se producirá.

IF (interrupt flan): indica si la condición de la interrupción se ha producido. Esresponsabilidad del usuario borrar dicho bit antes de regresar de la ISR.

IP (interrupt priority): indica si la prioridad asociada a la interrupción es alta (1) o baja (0). Obviamente, solo tiene efecto si está activado el modo de niveles de prioridad.

Consideremos por ejemplo la interrupción asociada la temporizador TMR0. Un temporizador essimplemente un contador que se incrementa con cada ciclo máquina (4 ciclos del oscilador). Dichocontador puede configurarse como de 8 o 16 bits. Cuando dicho contador rebosa y pasa de 0xFF a 0x00(modo 8 bits) o de 0xFFFF a 0x0000 (modo 16 bits) la bandera IF asociada a la interrupción del TMR0 sepone a 1. Para activar o desactivar la interrupción, establecer su prioridad o acceder al valor de subandera de interrupción definiríamos los siguiente macros:

#define enable_TMR0_int INTCONbits.TMR0IE=1

#define disable_TMR0_int INTCONbits.TMR0IE=0

#define TMR0_flag INTCONbits.TMR0IF

#define set_TMR0_high INTCON2bits.TMR0IP=1

#define set_TMR0_low INTCON2bits.TMR0IP=0

Las dos primeras líneas activan o desactivan la interrupción a través del correspondiente bit de IE. Latercera define el flag (IF) asociado al temporizador como TMR0_flag. Finalmente las dos últimasestablecen la interrupción del TMR0 como de alta o baja prioridad, modificando el correspondiente bit IP.

Algunas interrupciones pueden tener algunos bits extras dedicados. Por ejemplo, en la interrupción INT0(asociada a detectar cambios en el pin RB0) podemos especificar si la interrupción salta al pasar de nivelalto a bajo o viceversa.

Como se observa en los ejemplos anteriores todos los bits que hemos visto hasta ahora están en losregistros especiales INTCON e INTCON2. Al ir añadiendo más fuentes de interrupción se han tenido quecrear nuevos registros para interrupciones de periféricos (PIEx,PIRx), lugares donde almacenar los bitsde prioridades (IPRx), etc.

Podemos repetir las definiciones anteriores para el resto de las interrupciones. Cada interrupción tendríauna serie de definiciones similares a las listadas anteriormente para TMR0. Por ejemplo, para lainterrupción INT1 tenemos definidas:

#define enable_INT1_int INTCON3bits.INT1IE=1

#define disable_INT1_int INTCON3bits.INT1IE=0

#define INT1_low2high INTCON2bits.INTEDG1=1

#define INT1_high2low INTCON2bits.INTEDG1=0

#define INT1_flag INTCON3bits.INT1IF

#define set_INT1_high INTCON3bits.INT1IP=1

#define set_INT1_low INTCON3bits.INT1IP=0

De esta forma tendríamos una forma sencilla de activar una u otra interrupción, consultar sus banderas yestablecer su prioridad sin tener que recordar la posición de los diferentes bits en los registros. Lo usuales guardar dichas definiciones en un fichero que incluiríamos en nuestros proyectos. El fichero que usareen sucesivos programas es int_defs_C18.h.

Para el resto de las interrupciones tenemos similares definiciones, sin más que cambiar TMR0 o INT1 porel código de la interrupción en cuestión. Entre las interrupciones que más usaremos podemos destacar:

Temporizadores/Contadores (TMR0, TMR1, TMR2, TMR3)

La interrupción se produce al rebosar y pasar por 0 los contadores asociados.

Cambios en pines (INT0, INT1, INT2, RB)

INTx: La interrupción se produce con un cambio en el nivel de los pines RB0, RB1 y RB2 respectivamente.Es posible establecer si la interrupción se produce en el flanco ascendente o descendente (verINT1_low2high e INT1_high2low en los ejemplos citados antes).

RB: se produce ante cualquier cambio en los pines RB4 a RB7. Al contrario que las anteriores no esposible especificar un pin o una transición determinada.

Puerto serie (Rx,Tx)

RX, interrupción producida con la recepción de un carácter.

TX, interrupción de transmisión que nos avisa cuando el buffer de transmisión está libre para mandar un

Antonio

Ver todo mi perfil

DATOS PERSONALES

Participar en este sitioGoogle Friend Connect

Miembros (39) Más »

¿Ya eres miembro? Iniciar sesión

SEGUIDORES

Page 3: Tutoriales PIC_ Interrupciones (Conceptos Básicos)

24/6/2016 Tutoriales PIC: Interrupciones (conceptos básicos)

http://picfernalia.blogspot.com.ar/2012/06/interrupcionesconceptosbasicos.html 3/6

nuevo carácter.

Conversor Analógico/Digital (AD)

AD, nos avisa cuando se ha completado una conversión AnalógicaDigital.

Rutinas de servicio de interrupciones (ISRs)

Como hemos visto, para que una interrupción se produzca, los siguientes bits deben estar a 1:

GIE > Habilita todas las interrupciones

PEIE > Necesario (además de GIE) para las interrupciones periféricas.

El bit IE (int enable) de la interrupción deseada, habilitando dicha interrupción en particular.

El bit IF (int flag) de la interrupción, indicando que la condición de la interrupción se ha producido.

Es responsabilidad del usuario activar los tres primeros bits con los correspondiente comandos enable quehemos definido. Por ejemplo para activar la interrupción del timer 0, TMR0, haríamos:

enable_global_ints; // Enable global ints

enable_TMR0_int; // Enable TMR0 int

Si deseáramos activar la interrupción de recepción del puerto serie (RX) haríamos:

enable_global_ints; // Enable global ints

enable_perif_ints; // Enable peripheral ints

enable_RX_int; // Enable RX int

Con los tres primeros bits en 1, cuando se cumpla una condición de interrupción el microcontroladorpondrá a 1 el correspondiente bit IF y la interrupción se producirá. El microcontrolador pasará el control ala posición 0x0008.

Cuando esto suceda es fundamental que en dicha posición tengamos un código válido para gestionar lainterrupción. A dicho código se le denomina rutina de servicio de la interrupción (Interrupt Service Routineo ISR).

Las funciones mínimas de una ISR son las siguientes:

Determinar que interrupción se ha producido, ya que en principio todas las interrupciones seprocesan en la misma rutina. Esto lo haremos chequeando que IF bit está a 1. Obviamente no seránecesario chequear las flags de todas las interrupciones, sino sólo de aquellas que estén habilitadas.

Una vez determinada que interrupción en particular ha sucedido, ejecutar el código que sirve a dichainterrupción.

Finalmente, antes de volver, poner a 0 la correspondiente bandera IF. Si no lo hacemos, en cuantodevolvamos el control a la rutina principal se volverá a verificar la condición de interrupción yvolveremos a entrar en la ISR.

Hemos dicho que ante una interrupción el PIC saltará a una dirección determinada. ¿Cómo podemos ponerel código de la ISR en la posición de memoria adecuada? Eso va a depender del compilador. Usualmentelos compiladores nos facilitan dicha tarea teniendo una rutina de nombre predefinido para lasinterrupciones. Si se define una rutina con dicho nombre el compilador la pondrá en la posición adecuadaal compilar por lo que se ejecutará

Veremos como lo hacen el C18 de Microchip y el MikroC Pro de Mikroelektronica.

Compilador C18:

#pragma interrupt high_ISR

void high_ISR (void)

if (TMR0_flag) // ISR de la interrupcion de TMR0

PORTCbits.RC0=1; Delay10KTCYx(255); PORTCbits.RC0=0;

TMR0_flag=0;

Page 4: Tutoriales PIC_ Interrupciones (Conceptos Básicos)

24/6/2016 Tutoriales PIC: Interrupciones (conceptos básicos)

http://picfernalia.blogspot.com.ar/2012/06/interrupcionesconceptosbasicos.html 4/6

// Code @ 0x0008 > Jumps to ISR routine

#pragma code high_vector = 0x0008

void code_0x0008(void) _asm goto high_ISR _endasm

#pragma code

La primera parte del código usa #pragma interrupt para indicarle al compilador que la rutina siguientees una interrupción (una interrupción debe volver con una instrucción especial, Return from Interrupt, envez de un Return normal). El nombre usado high_ISR() es arbitrario y podemos cambiarlo por el quequeramos.

La rutina high_ISR() se ejecutará al producirse cualquier interrupción. Por eso lo primero que hacemoses chequear que interrupción ha causado la llamada a la ISR, consultando las posibles IF de lasinterrupciones posibles (las habilitadas). En este caso que tenemos una sola interrupción habilitadapodríamos evitar dicha comprobación.

Una vez verificado (TMR0_flag==1) que efectivamente estamos ahí por una interrupción del TMR0simplemente escribimos el código que deseemos ejecutar. ¿Qué es lo que se hace en la ISR del TMR0?Poca cosa: levantamos el pin RC0, esperamos 255x10000 ciclos de reloj (unos 0.5 segundos) y ponemosde nuevo a 0 el pin RC0 antes de regresar. El delay podría representar el tiempo que estaríamosocupados haciendo lo que se supone que tendríamos que hacer cada cierto tiempo. Mientras veamosencendido RC0 es que estamos dentro de la ISR. Muy importante: antes de regresar reseteamos labandera (TMR0_flag=0) para evitar entrar de nuevo en la interrupción.

La segunda parte del código usa la directiva #pragma code que nos permite posicionar un código en unadirección de memoria dada. Se define una nueva función code_0x0008 (de nuevo un nombre arbitrario)cuyo código es muy sencillo, simplemente un salto a la rutina high_ISR anterior.

Se ve que C18 deja ver lo que realmente está pasando. En la posición 0x0008 no podríamos meter unarutina muy grande (al fin y al cabo en 0x0018 podríamos tener otra rutina, la de la interrupción de bajonivel). Lo único que metemos es un salto a la verdadera rutina de interrupción high_ISR().

MikroC Pro:

En el caso del compilador MikroC Pro, hay una rutina de nombre reservado, interrupt( ). Veamos comoescribiríamos el código anterior para MikroC Pro.

void interrupt(void) // High priority interrupt

if (TMR0_flag) // TMR0 ISR

PORTC.RC0=1; delay_ms(600); PORTC.RC0=0;

TMR0_flag=0;

Vemos que el código es más sencillo. Basta declarar la función (reservada) interrupt y el compilador seocupa de todo. Por debajo el compilador MikroC Pro hará lo mismo que el C18 (escribir el código en algúnsitio y poner un salto en 0x0008 a esa dirección), pero la ventaja (o inconveniente según se mire) es quehace que el usuario se despreocupe de los detalles.

Nosotros seguiremos a partir de ahora la programación en C18. De hecho, las únicas diferencias eran enla forma de declarar las interrupciones, ya que el programa principal sería idéntico en amboscompiladores.

Lo único que tenemos que hacer en el main() es configurar de forma adecuada TMR0 para que salte en eltiempo deseado. Para ello damos cierto valor al registro T0CON (veremos detalles de cómo se hace en laentrada dedicada a los temporizadores). Tras programar el temporizador lo único que queda es habilitarlas interrupciones globales y la interrupción del TMR0 en particular:

void main()

TRISC=0; PORTC=0x00; // PORTC output

T0CON = 0b10000110; // Starts TMR0, rolls over every 128x65536 cycles = 1.67 sec @ 20 Mhz

enable_TMR0_int; // Enable Timer0 interrupt

enable_global_ints; // Enable global ints

while(1);

Vemos que en el bucle principal no hacemos nada. Sin embargo, al ejecutar el programa veremos como el

Page 5: Tutoriales PIC_ Interrupciones (Conceptos Básicos)

24/6/2016 Tutoriales PIC: Interrupciones (conceptos básicos)

http://picfernalia.blogspot.com.ar/2012/06/interrupcionesconceptosbasicos.html 5/6

Publicado por Antonio

pin RC0 parpadea: cada 1.6 segundos entra la interrupción en la que RC0 se pone en 1 (LED encendido) ypermanece así durante 600 msec, apagándose hasta el próximo ciclo.

La moraleja: aunque nuestro programa principal no este haciendo nada, el microcontrolador puede estarhaciendo cosas a través del código asociado a las interrupciones habilitadas. Veremos la aplicación deeste principio en otras aplicaciones.

Podéis comprobar que si comentáis cualquiera de las dos líneas enable el LED en RC0 permaneceapagado, ya que la interrupción no se ejecuta al no estar habilitada (o al no estar habilitadas lainterrupciones de forma global).

Es importante que siempre que habilitemos una interrupción tengamos definida la correspondiente funciónde manejo de interrupciones (posicionada en 0x0008). Si no es así, al producirse la interrupción y saltarel programa a la dirección 0x0008, al no encontrar un código valido en esa dirección el comportamientoes impredecible.

Recomendar esto en Google

10 comentarios:

Maikel in Australia 14 de noviembre de 2013, 21:18

Simplemente genial la explicación :)Muchas gracias y sigue así!!

Responder

oscar ordaz 28 de marzo de 2014, 22:01

Hola qutal me gustaria como hacer una interrupcion usart en pic basic pro

Responder

TIM408 5 de abril de 2014, 18:24

Responder

Este comentario ha sido eliminado por el autor.

TIM408 5 de abril de 2014, 18:25

Graciaaaaaaaas!!!

Responder

CARLOS EDGAR BUITRON QUISPE 24 de abril de 2014, 3:46

excelente amigo todos tus programas explicacion coo de un profesor, podrias explicar mas de os fusescomo usay y no usar PLL como hacer un bootloader en Pic 18f2550 o 18f4550 usando C18 y no CCS.

Responder

Anónimo 8 de mayo de 2014, 23:28

Tremendo aporte amigo, sigue así :)

Responder

Iván Talijancic 16 de mayo de 2014, 16:11

Muy buena explicación, simplemente clarisimo!!!... Gracias!

Responder

Wagner Jimenez 28 de mayo de 2014, 3:51

Excelente aporte, muy claro.

Responder

Anónimo 10 de diciembre de 2014, 3:07

Page 6: Tutoriales PIC_ Interrupciones (Conceptos Básicos)

24/6/2016 Tutoriales PIC: Interrupciones (conceptos básicos)

http://picfernalia.blogspot.com.ar/2012/06/interrupcionesconceptosbasicos.html 6/6

Entrada más reciente Entrada antiguaPágina principal

Suscribirse a: Enviar comentarios (Atom)

Introduce tu comentario...

Comentar como: Seleccionar perfil...

Publicar Vista previa

algún ejemplo de 3 led y 3 botones cada led para cada botón

Responder

Anónimo 25 de abril de 2016, 8:10

Eres el primero al que le entiendo el uso de las interrupciones, muchas gracias

Responder

Plantilla Picture Window. Con la tecnología de Blogger.