PIC32 deja de recibir interrupciones

0

Tengo un PIC32MX y estoy usando la interfaz UART para comunicarme con un dispositivo externo. La primera vez que enciendo el PIC, puedo recibir interrupciones en UART1 cuando recibo un byte de datos. Sin embargo, después de un corto período de tiempo (< 1 minuto) dejaré de recibir interrupciones de UART. Aquí está el esquema básico de código que estoy usando para probar esto:

void DelayUs(unsigned int delay) {
    unsigned int int_status;
    while (delay--) {
        int_status = INTDisableInterrupts();
        OpenCoreTimer(SYS_FREQ / 2000000);
        INTRestoreInterrupts(int_status);
        mCTClearIntFlag();
        while (!mCTGetIntFlag());
    }
    mCTClearIntFlag();
}

extern "C"{
void __ISR(_UART_1_VECTOR, ipl2) IntUart1Handler(void) {
    // Is this an RX interrupt?
    if (INTGetFlag(INT_U1RX)) {
        uint8_t data = (UARTGetData(UART1)).data8bit;
        // Clear the RX interrupt Flag
        INTClearFlag(INT_U1RX);
    }

    // We don't care about TX interrupt
    if (INTGetFlag(INT_U1TX)) {
        INTClearFlag(INT_U1TX);
    }
}
}

main(){
    UARTConfigure(UART1, UART_ENABLE_PINS_TX_RX_ONLY );
    UARTSetFifoMode(UART1, UART_INTERRUPT_ON_TX_NOT_FULL |UART_INTERRUPT_ON_RX_NOT_EMPTY);
    UARTSetLineControl(UART1, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
    UARTSetDataRate(UART1, GetPeripheralClock(), 16660);
    UARTEnable(UART1, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));

    // Configure UART RX Interrupt
    INTEnable(INT_SOURCE_UART_RX( UART1 ), INT_ENABLED);
    INTSetVectorPriority(INT_VECTOR_UART( UART1 ), INT_PRIORITY_LEVEL_2);
    INTSetVectorSubPriority(INT_VECTOR_UART( UART1 ), INT_SUB_PRIORITY_LEVEL_0);

    //set up the output and input pins for UART1
    TRISBbits.TRISB7 = 0;  //RB7 = TX
    TRISBbits.TRISB6 = 1; //RB6 = RX
    RPB7Rbits.RPB7R = 1; //RPB7 = U1TX
    U1RXRbits.U1RXR = 1; //RPB6 = U1RX

    // we can turn on interrupts now
    INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);
    INTEnableInterrupts();

    while (1) {
        // Do work here...

        DelayUs(100); //wait .1mS until next ping
                        //This is in reality ~200 uS
    }
}

Estoy probando para ver si todavía recibo interrupciones al establecer un punto de interrupción en el ISR usando MPLABX y un ICD3. Puedo activar los datos entrantes en el PIC. Cuando todo funciona bien, puedo establecer / eliminar el punto de interrupción en el ISR, pero después de un cierto punto el ISR ya no se activa más.

Creo que lo que podría estar sucediendo es que recibo una interrupción de TX cuando estoy retrasando mi ciclo principal como parte de la función DelayUs . ¿Podría eso suceder? ¿Hay algo más que pueda hacer que la interrupción deje de dispararse?

    
pregunta rm5248

2 respuestas

1

Pensamiento rápido. Cuando deshabilita las interrupciones en sus DelayUs, puede que esté llenando el FIFO en el búfer RX. Después de ese punto, la interrupción puede no activarse porque el búfer está lleno. Mire en la interrupción de desbordamiento del búfer de recepción.

    
respondido por el Michael
1

Falta el controlador de errores de trama en el ISR. Debería ser algo como esto -

Función de inicialización interna

mU2EIntEnable(1);

Dentro de ISR

    if (mU1EGetIntFlag()) {
    resetrx();//clear rx buffer here, read rxreg x 4
    U1STAbits.OERR = 0;
    mU1EClearIntFlag();
    return;
}

Además, asegúrese de utilizar las rutinas de escritura atómica Xclr y Xset para borrar cualquier indicador de interrupción. Ejemplo: las definiciones de lib del tipo mU1EClearIntFlag () son atómicas.

Acabo de descubrir que la bandera se puede corromper cuando se marca y cuando se dispara la interrupción en la serie 460f, si no está usando instrucciones claras de bits atómicos.

Ejemplo: Xbits.U1TXIF = 0 no es atómico en la serie pic32.

    
respondido por el Erik Friesen

Lea otras preguntas en las etiquetas