PIC18F14K50: Interrupciones (Interrupts)

9
Por: Omar Gurrola 04/09/13 http://www.proprojects.wordpress.com PIC18F14K50: Interrupciones (Interrupts) Una interrupción causa que el procesador responda a un evento interno o externo rápidamente. Esto genera que el procesador detenga la ejecución del programa y brinque a una parte especial de programa conocida como vector de interrupción (ISR) para que este bloque de código sea ejecutado y al terminar regrese para continuar con la ejecución normal del programa. Algunos uC tienen más de un vector de interrupción y se puede definir la prioridad de cada uno. Los vectores de interrupción se encuentran definidos en una dirección de memoria fija, esta dirección la define el fabricante. Las interrupciones son muy utilizadas, por ejemplo se requiere atención en una emergencia de energía o un incendio en una empresa, sobrecalentamiento del dispositivo, etc. Por lo que el procesador debe detener su ejecución normal y tomar acción inmediata. Para trabajar exitosamente con interrupciones debemos entender la estructura de hardware y las técnicas de programación necesaria. Fuentes y Estructura de Hardware de Interrupciones Este uC cuenta con diferentes fuentes de interrupciones y dos niveles de prioridad (High and Low). En general las interrupciones manejan tres tipos de bits para su control: Enable bit: Habilita el brinco a la ISR cuando ocurra un evento. Priority bit: Selecciona entre prioridad alta y baja. Flag bit: Indica que ha ocurrido un evento de interrupción. La estructura de hardware o lógica de las interrupciones del PIC18F14K50 es:

description

Interrupciones con PIC18

Transcript of PIC18F14K50: Interrupciones (Interrupts)

Page 1: PIC18F14K50: Interrupciones (Interrupts)

Por: Omar Gurrola 04/09/13 http://www.proprojects.wordpress.com

PIC18F14K50: Interrupciones (Interrupts)

Una interrupción causa que el procesador responda a un evento interno o externo rápidamente. Esto genera que el

procesador detenga la ejecución del programa y brinque a una parte especial de programa conocida como vector de

interrupción (ISR) para que este bloque de código sea ejecutado y al terminar regrese para continuar con la ejecución

normal del programa.

Algunos uC tienen más de un vector de interrupción y se puede definir la prioridad de cada uno. Los vectores de

interrupción se encuentran definidos en una dirección de memoria fija, esta dirección la define el fabricante.

Las interrupciones son muy utilizadas, por ejemplo se requiere atención en una emergencia de energía o un incendio en

una empresa, sobrecalentamiento del dispositivo, etc. Por lo que el procesador debe detener su ejecución normal y

tomar acción inmediata.

Para trabajar exitosamente con interrupciones debemos entender la estructura de hardware y las técnicas de

programación necesaria.

Fuentes y Estructura de Hardware de Interrupciones

Este uC cuenta con diferentes fuentes de interrupciones y dos niveles de prioridad (High and Low).

En general las interrupciones manejan tres tipos de bits para su control:

Enable bit: Habilita el brinco a la ISR cuando ocurra un evento.

Priority bit: Selecciona entre prioridad alta y baja.

Flag bit: Indica que ha ocurrido un evento de interrupción.

La estructura de hardware o lógica de las interrupciones del PIC18F14K50 es:

Page 2: PIC18F14K50: Interrupciones (Interrupts)

Por: Omar Gurrola 04/09/13 http://www.proprojects.wordpress.com Las fuentes de interrupción del PIC18F14K50 son las siguientes:

Source: E. Reg.: E. Bit: P. Reg.: P. Bit: F. Reg.: F. Bit: O. Reg.: O. Bit:

Timer0 INTCON<5> TMR0IE INTCON2<2> TMR0IP INTCON<2> TMR0IF - - Timer1 PIE1<0> TMR1IE IPR1<0> TMR1IP PIR1<0> TMR1IF - - Timer2 PIE1<1> TMR2IE IPR1<1> TMR2IP PIR1<1> TMR2IF - - Timer3 PIE2<1> TMR3IE IPR2<1> TMR3IP PIR2<1> TMR3IF - -

INT0 INTCON<4> INT0IE N/A (HP) N/A (HP) INTCON<1> INT0IF INTCON2<6> INTEDG0 INT1 INTCON3<3> INT1IE INTCON3<6> INT1IP INTCON3<0> INT1IF INTCON2<5> INTEDG1 INT2 INTCON3<4> INT2IE INTCON3<7> INT2IP INTCON3<1> INT2IF INTCON2<4> INTEDG2

IOC PA,PB INTCON<3> RABIE INTCON2<0> RABIP INTCON<0> RABIF INTCON2<7> /RABPU AD PIE1<6> ADIE IPR1<6> ADIP PIR1<6> ADIF

EUSART RX PIE1<5> RCIE IPR1<5> RCIP PIR1<5> RCIF EUSART TX PIE1<4> TXIE IPR1<4> TXIP PIR1<4> TXIF

MSSP PIE1<3> SSPIE IPR1<3> SSPIP PIR1<3> SSPIF CCP1 PIE1<2> CCP1IE IPR1<2> CCP1IP PIR1<2> CCP1IF

OSC Fail PIE2<7> OSCFIE IPR2<7> OSCFIP PIR2<7> OSCFIF C1 PIE2<6> C1IE IPR2<6> C1IP PIR2<6> C1IF C2 PIE2<5> C2IE IPR2<5> C2IP PIR2<5> C2IF

EE Write PIE2<4> EEIE IPR2<4> EEIP PIR2<4> EEIF Bus Collision PIE2<3> BCLIE IPR2<3> BCLIP PIR2<3> BCLIF

USB PIE2<2> USBIE IPR2<2> USBIP PIR2<2> USBIF

Manejo de Interrupciones Para el manejo de interrupciones se utilizan alrededor de 10 registros que son:

RCON.

INTCON, INTCON2, INTCON3.

PIR1, PIR2.

PIE1, PIE2.

IPR1, IPR2. En general las interrupciones se trabajan de dos maneras, una es modo compatible y el otro modo prioridad, las cuales se describen con más detalle en las siguientes secciones. Las interrupciones específicas de cada periférico serán vistas en el capítulo correspondiente al periférico.

Modo Compatible (Mid-Range Compatibility)

Este modo se utiliza para que el código sea compatible con dispositivos que no disponen de prioridades como el PIC16,

este modo está habilitado por default.

En este modo se ignoran los bits de prioridad (XIP), el vector de interrupción es 0008h únicamente y se utilizan los

siguientes bits:

INTCON<6>PEIE:

o Habilitar o deshabilitar la interrupción en los periféricos únicamente (AD, MSSP, EUSART).

INTCON<7>GIE:

o Habilita todas las interrupciones excepto periféricos

o Deshabilita todas las interrupciones, incluyendo periféricos.

Para configurar una o más interrupciones utilizar la siguiente secuencia:

1. Configurar las interrupciones que se vayan a utilizar (input, habilitarla, edge, borrar bandera, etc.).

2. Deshabilitar las prioridades (Modo compatible).

3. Habilitar la interrupción de periféricos (si se va a utilizar) y la interrupción general.

4. En la ISR verificar que bandera genero la interrupción y poner su código de servicio.

5. En la ISR al terminar su código de servicio borrar la bandera que género la interrupción.

Page 3: PIC18F14K50: Interrupciones (Interrupts)

Por: Omar Gurrola 04/09/13 http://www.proprojects.wordpress.com main.c

/* * Copyright (c) 2011-2013, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 04/08/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" /** DECLARATIONS ***************************************************/ /** VARIABLES ******************************************************/ /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm } #pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. if(INT0Flag == 1){ lcd_goto(4,1); lcd_write_pgm(" INT0 Event "); INT0FlagClear(); } else if(INT1Flag == 1){ lcd_goto(4,1); lcd_write_pgm(" INT1 Event ");

Page 4: PIC18F14K50: Interrupciones (Interrupts)

Por: Omar Gurrola 04/09/13 http://www.proprojects.wordpress.com INT1FlagClear(); } else if(INT2Flag == 1){ lcd_goto(4,1); lcd_write_pgm(" INT2 Event "); INT2FlagClear(); } } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ SetClockTo32MHz(); lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" Pro Projects "); lcd_goto(2,1); lcd_write_pgm(" INT Testing... "); // INT0 configuration OpenInRC0(); INT0Enable(); INT0FEdg(); INT0FlagClear(); // INT1 configuration OpenInRC1(); INT1Enable(); INT1FEdg(); INT1FlagClear(); // INT1 configuration OpenInRC2(); INT2Enable(); INT2FEdg(); INT2FlagClear(); // General INT configuration INTPDisable(); // Enable compatiblity mode GIEnable(); // Enable all int while(true){ Sleep(); } // end while } // end main()

Diagrama esquemático:

Page 5: PIC18F14K50: Interrupciones (Interrupts)

Por: Omar Gurrola 04/09/13 http://www.proprojects.wordpress.com Circuito armado:

Modo Prioridad (Interrupt With Priority)

En este modo se puede definir la prioridad de cada interrupción que se va a utilizar, la ventaja de poder definir esto es

en los casos donde hay uno o varios eventos que deben ejecutarse antes que cualquier otra cosa. Una interrupción de

alta prioridad puede interrumpir una de baja prioridad.

Los vectores de interrupción son:

0008h: Alta prioridad

0018h: Baja prioridad

En este modo se trabajan con los siguientes registros:

RCON<7>IPEN: Habilita o deshabilita el manejo de prioridades

INTCON<7>GIEH:

o Habilita solamente las interrupciones de alta prioridad

o Deshabilita todas las interrupciones (alta y baja).

INTCON<6>GIEL:

o Habilita las interrupciones de baja prioridad, solamente cuando GIEH = 1.

o Deshabilita las interrupciones de baja prioridad únicamente.

Para configurar una o más interrupciones con prioridad utilizar la siguiente secuencia:

1. Configurar las interrupciones que se vayan a utilizar (input, habilitarla, edge, borrar bandera, etc.).

2. Habilitar las prioridades.

3. Habilitar la interrupción de periféricos (si se va a utilizar) y la interrupción general.

4. En la ISR verificar que bandera genero la interrupción y poner su código de servicio.

5. En la ISR al terminar su código de servicio borrar la bandera que género la interrupción.

Page 6: PIC18F14K50: Interrupciones (Interrupts)

Por: Omar Gurrola 04/09/13 http://www.proprojects.wordpress.com main.c

/* * Copyright (c) 2011-2013, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 04/08/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" /** DECLARATIONS ***************************************************/ /** VARIABLES ******************************************************/ u8 LastValue; /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm } #pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. if(INT0Flag == 1){ lcd_goto(3,1); lcd_write_pgm(" INT0 Event - HP "); lcd_goto(4,1); lcd_write_pgm("Rising Event Ocurred"); Waitmsx(1000); INT0FlagClear(); }

Page 7: PIC18F14K50: Interrupciones (Interrupts)

Por: Omar Gurrola 04/09/13 http://www.proprojects.wordpress.com } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. u8 XORValue; if(INTPABFlag == 1){ lcd_goto(3,1); lcd_write_pgm(" IOCB Event - LP "); // Check pins for changes XORValue = LastValue ^ ReadPB(); LastValue = ReadPB(); // Update value lcd_goto(4,1); switch(XORValue){ case 16: lcd_write_pgm(" RB4 Changed! "); break; case 32: lcd_write_pgm(" RB5 Changed! "); break; case 64: lcd_write_pgm(" RB6 Changed! "); break; case 128: lcd_write_pgm(" RB7 Changed! "); break; } Waitmsx(1000); lcd_goto(4,1); lcd_write_pgm(" "); lcd_goto(3,1); lcd_write_pgm(" "); // Before cleaning the flag we must read the port (otherwise the flag will never be clear) INTPABFlagClear(); } } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ SetIntClockTo32MHz(); lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" Pro Projects "); lcd_goto(2,1); lcd_write_pgm(" Priority Testing "); // PORTB IOC Configuration OpenInPB(); // Open in PORTB WPUBEnable(); // Enable WPU // PORTB INT Configuration IOCBEnable(); // Enable IOC INTPABLPriority(); // Set Priority (Low) INTPABEnable(); // Enable INT INTPABFlagClear(); // Clear INT Flag // INT0 Configuration INT0FEdg(); // Falling edge INT0Enable(); // INT0 Enable INT0FlagClear(); // Clear flag // General INT configuration OpenInRC0(); // Input INTPEnable(); // Priority mode GIEHEnable(); // Enable HP int GIELEnable(); // Enable LP int // Read actual port value LastValue = ReadPB(); while(true){ Sleep(); } // end while } // end main()

Page 8: PIC18F14K50: Interrupciones (Interrupts)

Por: Omar Gurrola 04/09/13 http://www.proprojects.wordpress.com Diagrama esquemático:

Circuito armado:

Page 9: PIC18F14K50: Interrupciones (Interrupts)

Por: Omar Gurrola 04/09/13 http://www.proprojects.wordpress.com

Referencias

Microchip, “PIC18F/LF1XK50 Data Sheet”, 2010,

http://ww1.microchip.com/downloads/en/DeviceDoc/41350E.pdf

Dogan Ibrahim, “Advanced PIC Microcontroller Projects in C”, 2008

Tim Wilmshurst, “Designing Embedded Systems With PIC Microcontrollers”, 2010