PIC18F14K50: Interrupciones (Interrupts)

Page 1

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:


Por: Omar Gurrola 04/09/13 Las fuentes de interrupción del PIC18F14K50 son las siguientes:

http://www.proprojects.wordpress.com

Source:

E. Reg.:

E. Bit:

P. Reg.:

P. Bit:

F. Reg.:

F. Bit:

O. Reg.:

O. Bit:

Timer0 Timer1 Timer2 Timer3 INT0 INT1 INT2 IOC PA,PB AD EUSART RX EUSART TX MSSP CCP1 OSC Fail C1 C2 EE Write Bus Collision USB

INTCON<5> PIE1<0> PIE1<1> PIE2<1> INTCON<4> INTCON3<3> INTCON3<4> INTCON<3> PIE1<6> PIE1<5> PIE1<4> PIE1<3> PIE1<2> PIE2<7> PIE2<6> PIE2<5> PIE2<4> PIE2<3> PIE2<2>

TMR0IE TMR1IE TMR2IE TMR3IE INT0IE INT1IE INT2IE RABIE ADIE RCIE TXIE SSPIE CCP1IE OSCFIE C1IE C2IE EEIE BCLIE USBIE

INTCON2<2> IPR1<0> IPR1<1> IPR2<1> N/A (HP) INTCON3<6> INTCON3<7> INTCON2<0> IPR1<6> IPR1<5> IPR1<4> IPR1<3> IPR1<2> IPR2<7> IPR2<6> IPR2<5> IPR2<4> IPR2<3> IPR2<2>

TMR0IP TMR1IP TMR2IP TMR3IP N/A (HP) INT1IP INT2IP RABIP ADIP RCIP TXIP SSPIP CCP1IP OSCFIP C1IP C2IP EEIP BCLIP USBIP

INTCON<2> PIR1<0> PIR1<1> PIR2<1> INTCON<1> INTCON3<0> INTCON3<1> INTCON<0> PIR1<6> PIR1<5> PIR1<4> PIR1<3> PIR1<2> PIR2<7> PIR2<6> PIR2<5> PIR2<4> PIR2<3> PIR2<2>

TMR0IF TMR1IF TMR2IF TMR3IF INT0IF INT1IF INT2IF RABIF ADIF RCIF TXIF SSPIF CCP1IF OSCFIF C1IF C2IF EEIF BCLIF USBIF

INTCON2<6> INTCON2<5> INTCON2<4> INTCON2<7>

INTEDG0 INTEDG1 INTEDG2 /RABPU

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. 2. 3. 4. 5.

Configurar las interrupciones que se vayan a utilizar (input, habilitarla, edge, borrar bandera, etc.). Deshabilitar las prioridades (Modo compatible). Habilitar la interrupción de periféricos (si se va a utilizar) y la interrupción general. En la ISR verificar que bandera genero la interrupción y poner su código de servicio. En la ISR al terminar su código de servicio borrar la bandera que género la interrupción.


Por: Omar Gurrola main.c /* * * * * * * * * * * * * * * * * * * * * * */

04/09/13

http://www.proprojects.wordpress.com

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(" INT0FlagClear(); } else if(INT1Flag == 1){ lcd_goto(4,1); lcd_write_pgm("

INT0 Event

");

INT1 Event

");


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(" lcd_goto(2,1); lcd_write_pgm("

Pro Projects

");

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:


Por: Omar Gurrola Circuito armado:

04/09/13

http://www.proprojects.wordpress.com

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. 2. 3. 4. 5.

Configurar las interrupciones que se vayan a utilizar (input, habilitarla, edge, borrar bandera, etc.). Habilitar las prioridades. Habilitar la interrupción de periféricos (si se va a utilizar) y la interrupción general. En la ISR verificar que bandera genero la interrupción y poner su código de servicio. En la ISR al terminar su código de servicio borrar la bandera que género la interrupción.


Por: Omar Gurrola main.c /* * * * * * * * * * * * * * * * * * * * * * */

04/09/13

http://www.proprojects.wordpress.com

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(); }


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(); WPUBEnable(); // // PORTB INT Configuration IOCBEnable(); // INTPABLPriority(); // INTPABEnable(); // INTPABFlagClear(); // // INT0 Configuration INT0FEdg(); INT0Enable(); INT0FlagClear(); // General INT OpenInRC0(); INTPEnable(); GIEHEnable(); GIELEnable();

");

// Open in PORTB Enable WPU Enable IOC Set Priority (Low) Enable INT Clear INT Flag

// Falling edge // INT0 Enable // Clear flag

configuration // Input // Priority mode // Enable HP int // Enable LP int

// Read actual port value LastValue = ReadPB(); while(true){ Sleep(); } // end while } // end main()

");


Por: Omar Gurrola Diagrama esquemรกtico:

Circuito armado:

04/09/13

http://www.proprojects.wordpress.com


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


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.