3 votos

La interrupción de alta prioridad del PIC18 no interrumpe la baja (xc8)

Estaba intentando aprender e implementar la propiedad de prioridad de las interrupciones en el PIC18F46K22 uC. Yo uso MPLABX y XC8 compilador.

En mi código (transformado a partir de un código de ejemplo), tengo una interrupción externa (INT1) y una interrupción de recepción USART (RC1IF). La entrada externa es un controlador de LED y la USART es un simple programa de eco manejado por un terminal de PC.

A continuación se presentan algunas partes del código, con comentarios. El código se construye con éxito. Pero con esta combinación "high-low", cuando la USART está activa y el programa hace un eco del texto a la terminal, no puedo interrumpir la transmisión con la interrupción externa que ha dado un pulsador.

Aquí están los ISR.

void interrupt low_priority USB(void)
{

if (PIR1bits.RC1IF==1)  // check if receive interrupt has fired
{
    t = RCREG1;      // read received character to buffer

    // check if received character is not new line character
    // and that maximum string length has not been reached
    if ( (t != '\n') && (rcindex < STRLEN) )
    {
        rcbuf[rcindex] = t; // append received character to string
        rcindex++;          // increment string index
    }
    else
    {
        rcindex = 0;         // reset string index
        USART_puts(rcbuf);  // echo received string

        for(int x=0; x<STRLEN+1; x++){ //clear
                rcbuf[x] = 0;           // any leftover
            }                           // from
        RCREG1 = 0x00;                  // last
        TXREG1 = 0x00;                  // transmission
    }

    PIR1bits.RCIF = 0;      // reset receive interrupt flag
}
}

y

void interrupt high_priority inticik(void)
{
if(INTCON3bits.INT2IF==1)
{
    LATAbits.LA1 = ~LATAbits.LA1;
    __delay_ms(20);
}

INTCON3bits.INT2IF = 0;
}

Esta es la función de configuración de la interrupción;

void interrupt_config(void)
{
 //interrupt main configuration
RCONbits.IPEN = 1;        // interrupt priority mode enabled, H or L interrupts
INTCONbits.GIE_GIEH = 1;  // high priority interrupts are enabled
INTCONbits.PEIE_GIEL = 1; // low priority interrupts are enabled

//pin interrupt 1&2 enable + priority assignments + edge selection
TRISBbits.TRISB2 = 1;
ANSELBbits.ANSB2 = 0;
INTCON3bits.INT1IE = 1; // int1 is enabled
INTCON3bits.INT2IE = 1; // int2 is enabled
INTCON3bits.INT1IP = 1; // int1 is high priority
INTCON3bits.INT2IP = 1; // int2 is high priority
INTCON2bits.INTEDG1 = 1;  // rising edge
INTCON2bits.INTEDG2 = 1;  // rising edge

//EUSART interrupt enable + priority assignments

PIE1bits.RC1IE = 1; //receive interrupt enabled
PIE1bits.TX1IE = 1; //transmit interrupt enabled
IPR1bits.RC1IP = 0; // receive is low priority
IPR1bits.TX1IP = 0; // transmit is low priority
}

Y aquí está la función principal.

int main(void)
{
TRISAbits.TRISA1 = 0;
LATA = 0x00;
interrupt_config();

USART_init();

USART_puts("Init complete!\n");

//main loop
while(1)
{
    Sleep();
}

return 0;
}

Otras partes del código, como las funciones USART y las cabeceras de bits de conf. "config.h", no se proporcionan debido a su irrelevancia.

Gracias.

Editar

Me olvidé de mencionar, cuando cambio el,

"void interrupt low_priority USB(void)"

declaración a

"void interrupt high_priority USB(void)"

el programa funciona con éxito y se hace eco en el terminal. Pero cuando se establece como "low_priority", el módulo USART no funciona en el terminal. Sólo la interrupción externa funciona con éxito.

1 votos

Independientemente de la respuesta a tu (buena) pregunta, no deberías demorarte en una interrupción. Establece una bandera y retrasa en otra parte del programa principal.

0 votos

¿Está utilizando INT1 o INT2? El texto de introducción dice INT1, el código inicializa ambos y la interrupción utiliza INT2.

0 votos

Ambos pines INT1 e INT2 también tienen un comparador que no veo que se desactive. Todas las funciones analógicas necesitan ser deshabilitadas para usar un pin como entrada digital.

1voto

axel_c Puntos 111

Aunque no estoy seguro de por qué, esto resolvió mi problema.

From PIC18F46K22 Datasheet

En el Power-On-Reset, el bit ADON se borra, lo que significa que desactiva el convertidor A/D por defecto, ¿verdad? Esto significa que tanto si desactivo el convertidor A/D como si no, se desactiva automáticamente.

ADCON0bits.ADON = 0;

Pero, añadí esta línea a mi configuración y funcionó, ahora tanto la interrupción externa (alta prioridad) como la interrupción USART (baja prioridad) funcionan en el mismo programa.

Es una solución, pero sigo preguntándome por qué ha funcionado.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X