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
}