PIC24F UART Rx Interrupt no se dispara

1

Actualmente estoy intentando escribir código para un dimmer controlado por DMX de 48 canales usando un PIC24FJ32GA002. Usando un alcance, he confirmado que hay una señal DMX que llega al pin Rx del UART que se ha configurado correctamente usando la función PPS de la imagen. También se inhabilitan 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 dispara una o dos veces cuando los datos nulos alcanzan U1RXREG , luego falla al dispararse 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 envía al controlador PWM. dmxRecieveByte() toma el contenido de rxbyte y lo coloca en un búfer del tamaño correcto para almacenar un paquete DMX (512 bytes) para luego copiarlo en un búfer separado cuando se recibe el paquete.

ACTUALIZACIÓN: He cambiado los ISR para que haya controladores separados para los errores y los bytes entrantes, la función uartRecieve() ahora se ocupa de ordenar los bytes entrantes y los ISR se encargan de borrar los indicadores y demás. El Tx ISR está ahí como un 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, aún así se está ejecutando el ISR una vez que se ejecutan los programas y luego no vuelve a suceder. Tengo el hardware de producción ahora, así que todas las variables que se encontraban en ese archivo han sido eliminadas. Hurgó con una sonda de alcance y todo parece estar en orden con la señal.

Función de inicio 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
}
    
pregunta RobbG

2 respuestas

2

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 deshabilite. Se agregó algo de código de desactivación a la función de inicialización de hardware principal para deshabilitar el ADC en todos los pines y ahora funciona muy bien.

    
respondido por el RobbG
0

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

    
respondido por el brhans

Lea otras preguntas en las etiquetas