Nunca sale de la interrupción en C18

Hola, estoy haciendo un programa en el que cuando pulso a bajo RB0/INT0 en un PIC18F1320 el programa debe interrumpirse para hacer algo... Hasta acá todo bien, el problema es que una vez atendida la interrupción el programa no sale más. Se queda en LOOP infinito dentro de la interrupción.
He comprobado que el flag INT0IF se borra correctamente y que GIE queda en 0.. No encuentro el problema ni se me ocurre que puede ser. Saludos

Este es el código para las interrupciones:

Código:
// High priority interrupt routine
#pragma interrupt    high_isr
void    high_isr(void)
{
    if(INTCONbits.INT0IF)    //Se pulsó RB0 (Marcha/Parada)?
    {
    INTCONbits.INT0IF=0;        //Borro el flag
    //Atención a la interrupción!!!
    if(Marcha == 0)            //El motor está parado?
    {ArranqueSuave();    Marcha=1;}
    else
    {ClosePWM1();    Marcha=0;}
    }
}
//---------------------------------------------------------------------------- 
// Low priority interrupt routine
#pragma interruptlow    low_isr
void low_isr(void)
{}
//----------------------------------------------------------------------------
#pragma code high_vector=0x08//Interrupcion de alta prioridad en 08h

void    high_vector(void)
{
   _asm GOTO high_isr _endasm
}

#pragma code low_vector=0x18//Interrupcion de baja prioridad en 18h
void    low_vector(void)
{
   _asm GOTO low_isr _endasm
}

#pragma code
//----------------------------------------------------------------------------

Y por si alguno quiere verlo completo, aquí lo dejo también:
Código:
// Aplicación de una señal PWM a través del pin RB3

#include <p18f1320.h>    //Librería del micro a utilizar
#include <delays.h>        //Librería de retardos
#include <timers.h>        //Librería de funciones para los timers
#include <pwm.h>        //Librería de funciones PWM
#include <portb.h>        //Para interrupción externa del puerto B

#pragma config OSC = INTIO1, FSCM = OFF, IESO = OFF   // Configura CONFIG1H.
#pragma config PWRT = ON, BOR = OFF, BORV = 27    // Configura CONFIG2L.
#pragma config WDT = OFF, WDTPS = 32768           // Configura CONFIG2H.
#pragma config MCLRE = OFF                        // Configura CONFIG3H.
#pragma config STVR = ON, LVP = OFF, DEBUG = OFF  // Configura CONFIG4L.
#pragma config CP0 = OFF, CP1 = OFF               // Configura CONFIG5L.
#pragma config CPB = OFF, CPD = OFF               // Configura CONFIG5H.
#pragma config WRT0 = OFF, WRT1 =OFF              // Configura CONFIG6L.
#pragma config WRTC = OFF, WRTB = OFF, WRTD = OFF // Configura CONFIG6H.
#pragma config EBTR0 = OFF, EBTR1 = OFF           // Configura CONFIG7L.
#pragma config EBTRB = OFF                        // Configura CONFIG7H.

//---------------------------------------------------------------------------- 
//Declaración de variables globales
char Marcha=0;

//---------------------------------------------------------------------------- 
/*Declaración de funciones 
Si esto no se hace, la definición de la función DEBE hacerse antes de invocarla*/
void ArranqueSuave(void); //Función para encender y mostrar los displays
void EnableHighInterrupts(void);

//---------------------------------------------------------------------------- 
// High priority interrupt routine
#pragma interrupt    high_isr
void    high_isr(void)
{
    if(INTCONbits.INT0IF)    //Se pulsó RB0 (Marcha/Parada)?
    {
    INTCONbits.INT0IF=0;        //Borro el flag
    //Atención a la interrupción!!!
    if(Marcha == 0)            //El motor está parado?
    {ArranqueSuave();    Marcha=1;}
    else
    {ClosePWM1();    Marcha=0;}
    }
}
//---------------------------------------------------------------------------- 
// Low priority interrupt routine
#pragma interruptlow    low_isr
void low_isr(void)
{}
//----------------------------------------------------------------------------
#pragma code high_vector=0x08//Interrupcion de alta prioridad en 08h

void    high_vector(void)
{
   _asm GOTO high_isr _endasm
}

#pragma code low_vector=0x18//Interrupcion de baja prioridad en 18h
void    low_vector(void)
{
   _asm GOTO low_isr _endasm
}

#pragma code
//----------------------------------------------------------------------------


//Etiquetado de bits de algunos registros
#define T2ON T2CONbits.TMR2ON    // El bit TMR2ON del registro T2CON es
                                 // etiquetado como T2ON.
//Etiquetado de pines
#define PWM    PORTBbits.RB3

//=============================================================//
void main (void)        // FUNCIÓN PRINCIPAL
{
OSCCONbits.IRCF2=1;OSCCONbits.IRCF1=1;OSCCONbits.IRCF0=0; //Seteo el prescaler del Osc. interno para 4MHz
ADCON1 = 0x7F;        //Configura como I/O digitales los puertos A y B
TRISB = 0b10000111;    //RB3,4,5,6 salida y el resto entrada
TRISA = 0xFF;        //Configura puerto A todo como entrada

EnableHighInterrupts();

//La interrupción por INT0 siempre es de alta prioridad
OpenRB0INT(PORTB_CHANGE_INT_ON);    //Habilita interrupción por RB0/INT0
        PORTB_PULLUPS_ON;            //Configura RB0 como entrada
        FALLING_EDGE_INT;            //Interrumple en el flanco descendente

//Configuración de interrupciones de otra forma
INTCONbits.GIEL=1;        //Habilita interrupciones de baja prioridad
INTCON3bits.INT1IE=1;    //Habilita interrupción por RB1/INT1
INTCON3bits.INT1IP=0;    //INT1 de baja prioridad
INTCON2bits.INTEDG1=0;    //INT1 por flanco descendente
INTCONbits.INT0IF=0;    //Borro flag de esta interrupción
INTCON3bits.INT1IF=0;    //Borro flag de esta interrupción

while(1); //Espero a que se presione RB0


}
//=============================================================//

/*--------------------Funciones--------------------*/
void EnableHighInterrupts(void)
{
RCONbits.IPEN=1;        //Habilito prioridad en las interrupciones
INTCONbits.GIEH=1;        //Habilita interrupciones de alta prioridad
}
//--------------------------------------------------------------------------------

void ArranqueSuave() //FALTA ENCENDER LOS LEDS A MEDIDA QUE AUMENTA LA VELOCIDAD!!
{
unsigned int CicloUtil;
Marcha=1; //Motor encendido
// Configuración e inicialización del TIMER2    
OpenTimer2(TIMER_INT_ON | T2_PS_1_16 | T2_POST_1_1); // Enciende y configura TIMER2.
T2ON = 0;       // Detiene el TIMER2.
WriteTimer2(0); // Borra el TIMER2.
// Inicialización del ECCP. 
OpenPWM1(243);   // Carga el periodo (valor cargado en registro PR2).
// Configuración en modo PWM Salida única
SetOutputPWM1(SINGLE_OUT,PWM_MODE_1);       // P1A = Modul.(activo ALTO)
T2ON = 1;        // Enciende el TIMER2.

for(CicloUtil=0;CicloUtil=977;CicloUtil++)
{
while(TMR2 = 0) {}        //Espero a que se complete un periodo del PWM
SetDCPWM1(CicloUtil);  // Carga del ciclo útil (valor en CCPR1L:CCP1CON 5:4)
}
return;
}
...
 
Última edición por un moderador:
Atrás
Arriba