PIC24F UART Rx La interrupción no se activa

Actualmente estoy tratando de escribir código para un atenuador controlado por DMX de 48 canales usando un PIC24FJ32GA002. Usando un alcance, confirmé que hay una señal DMX que llega al pin Rx del UART que se configuró correctamente usando la función PPS de la imagen. También se deshabilitan las interrupciones anidadas.

A continuación se muestra el contenido de mi ISR ​​para la interrupción UART Rx. Lo que sucede cuando lo depuro con un punto de interrupción establecido dentro del ISR es que el ISR se activa una o dos veces con datos nulos que llegan U1RXREG, luego no se activa nuevamente y el programa se ejecuta sin más interrupciones.

El bucle principal del programa tiene un bucle que procesa los paquetes DMX entrantes y los envía al controlador PWM. dmxRecieveByte()toma el contenido rxbytey lo coloca en un búfer que tiene el tamaño adecuado para almacenar un paquete DMX (512 bytes) para luego copiarlo en un búfer separado cuando se recibe el paquete.

ACTUALIZACIÓN: Cambié los ISR para que haya controladores separados para errores y bytes entrantes, la uartRecieve()función ahora maneja la clasificación de los bytes entrantes y los ISR se encargan de borrar banderas y demás. El Tx ISR está allí como marcador de posición hasta que la funcionalidad DMX funcione correctamente.

ACTUALIZACIÓN 2: Se agregó el código de inicio de UART y el código Rx ISR actualizado, y aún se activa el ISR una vez en los programas que se ejecutan por primera vez y luego no vuelve a suceder. Ahora tengo el hardware de producción, por lo que se han eliminado todas las variables que estaban allí. Hurgué con una sonda de alcance y todo parece estar en orden en cuanto a la señal.

Función de inicio de UART

void dmxInit(void)
{

    DMX_UART_MODE    = 0b0000000000001001;
    DMX_UART_BAUD    = (FCY/(4*250000))-1;
    DMX_INT_PRIORITY = 0x07;

    PORTBbits.DMX_RX_MUX = 0;

    spareBufValid = 0;

    DMX_UART_ENABLE_BIT = 1;
    DMX_INT_ENABLE_BIT  = 1;
}

UART Rx ISR

void __attribute__ ((interrupt,no_auto_psv)) DMX_INTERRUPT_FUNC(void)
{
    uint8_t dmxData;

    if(DMX_OVERRUN_BIT)
    {   // Overrun error
        DMX_OVERRUN_BIT = 0;
        dmxReset();
    }
    else
    {   // empty any data in the UART fifo
        while(DMX_DATA_AVAIL_BIT)
        {
            if(DMX_FRAME_ERR_BIT)
            {   // frame error
                if(DMX_DATA_REG)
                {   // data is not 0 - not a break
                    dmxReset();
                }
                else
                {   // its a break!
                    breakDetected = 1;
                    startDetected = 0;

                    if(writeCount)
                    {
                        dmxWriteBufSwap();
                    }
                }
            }
            else
            {   // data in the fifo
                dmxData = DMX_DATA_REG;

                if(breakDetected)
                {
                    if(startDetected)
                    {   // some DMX data
                        if(rxCount == fixture.DMXStartAddress)
                        {
                            pByteWrite = pWriteBuf;
                        }

                        if(pByteWrite)
                        {
                            *pByteWrite++ = dmxData;
                            writeBufSize++;

                            if( (writeBufSize >= NumberOfChannels) || (rxCount >= NUM_DMX_CHANNELS-1) )
                            {   // finished receiving this packet
                                dmxWriteBufSwap();
                            }
                        }
                        rxCount++;
                    }
                    else
                    {   // This is the start code
                        if(dmxData == DMX_DATA_START_CODE)
                        {
                            startDetected  = 1;
                            writeBufSize   = 0;
                            rxCount        = 0;
                        }
                        else
                        {   // some other start code
                            dmxReset();
                        }
                    }
                }
            }
        }
    }
    DMX_INT_FLAG_BIT = 0;   // Clear interrupt flag
}
El ISR me parece correcto. Publique su inicialización.
¿Interrupciones globales habilitadas?

Respuestas (2)

Entonces resulta que esa familia de PIC tiene un módulo ADC que automáticamente tiene prioridad sobre cualquier otro componente y evita que los pines causen interrupciones hasta que se deshabilita. Se agregó un código de desactivación a la función de inicialización del hardware principal para desactivar el ADC en todos los pines y ahora funciona de maravilla.

Ese PIC tiene un vector de interrupción separado para errores UART.
Creo que encontrará que su UART está atascado en una condición de error no controlada y se niega a recibir más datos.
Le sugiero que mueva su código de verificación y manejo de errores de encuadre y desbordamiento a un nuevo controlador _U1ErrInterrupt.

Hay un controlador de interrupción separado para errores, veré si la reestructuración de mi código ayuda.
Muéstrenos su código de inicio UART también. Puede haber algo ahí...