ISR Usart Rx Problem (MPLAB C18)

diamel wrote on Friday, July 06, 2012:

Hi everyone, i have some weeks working with FreeRTOS. i’m ussing MPLAB C18 and now i have the next problem.

I’m ussing ISR for RX USART, i have used in the past in a normal project for MPLAB C18 but now i have to do it with freeRTOS and C18, I activate the ISR for USART from the port.c file:

/*
* Vector for ISR.  Nothing here must alter any registers!
*/
#pragma code high_vector=0x08
static void prvLowInterrupt( void )
{
/* Was the interrupt the tick? */
if( PIR1bits.CCP1IF )
{
_asm
goto prvTickISR
_endasm
}

/* Was the interrupt a byte being received? */

if( PIR1bits.RCIF )
{
_asm
goto vSerialRxISR
_endasm

}

/* Was the interrupt the Tx register becoming empty? */
/*if( PIR1bits.TXIF )
{
if( PIE1bits.TXIE )
{
_asm
goto vSerialTxISR
_endasm
}
}*/
}
#pragma code

diamel wrote on Friday, July 06, 2012:

when i enter in the interrupt (the program work and enter when the USART receive data) i put the PIR1bits.RCIF=0 for wait a new reception, but i can’t put the register in 0 is ever en 1 and the interrupt is ever entering even when i’m not receiving data.

#pragma interrupt vSerialRxISR
void vSerialRxISR( void )
{

PIR1bits.RCIF=0;

if(PIR1bits.RCIF==0)
{
putsTX(“PIR1bits.RCIF=0\r”,16);
}

if(PIR1bits.RCIF==1)
{
putsTX(“PIR1bits.RCIF=1\r”,16);
}

}

the program is printing PIR1bits.RCIF=1 even when i change the value before of the if.

i hope someone can helpme =)

richard_damon wrote on Saturday, July 07, 2012:

Normally, you need to take the character out of the RxBuffer before clearing the interrupt flag. so you want something like: (I am guessing on port names)

if(PIR1bits.RCIF){
    while(! PIR1bits.rxempty){
        char c;
        c = PIR1.rxbuff;
        /* put code to process character here, either send to queue or build message in a buffer */
    }
   PIR1bits.RCIF = 0;
}

Since the buffer isn’t empty, the port will assert the interrupt again immediately.

diamel wrote on Wednesday, July 11, 2012:

thanks richard!! you’re right i change the code to:

#pragma interrupt vSerialRxISR
void vSerialRxISR( void )
{

Data1=getcUSART();

if( RCSTAbits.OERR )
{

RCSTAbits.CREN = 0;
RCSTAbits.CREN = 1;
}

}

i get the data and clean and set CREN stat bit because if i don’t when i receive two o more bytes the recepcion crash, i have create a task for process the byte and only print in the display when i receive the valor i’m expecting.

static void vtask_read_USART( void *pvParameters ){

char Data;

for(;:wink:
{

if(Data1==‘A’)
{

INTCONbits.PEIE=0;

putsTX(“expecting character received”);

putcUSART(13);
while(BusyUSART());

Data1=0;

}
  

}