Electronic – PIC UART Interrupt Not Triggering

hi-tech-compilermicrocontrollerpic

I have PIC16F628A that I am trying to have read from UART. Without interrupts, it reads the first 3 bytes fine but hits an OERR. To combat this, I thought an interrupt would be good and load any received bytes into a buffer variable that could be read in later (ring buffer of array type char). But the interrupt is not triggering and I've run out of ideas.

CMCON = 0x07;           //16F627/8 spcial function reg (RAx is port)
CCP1CON = 0b00000000;   //Capt/Comp/PWM off

OPTION_REG = 0b00000000;

T1CON = 0;
INTCON = 0;
PIR1 = 0;
GIE = 0;

PIE1 = 0;

BRGH = 1;   /* high baud rate */
SPBRG = 19200;  /* set the baud rate */

SYNC = 0; //Async
TXEN = 0; //Disable transmit
TXIE = 0; //Disable transmit interrupt
RCIE = 1; //Enable Receive interrupt
SPEN = 1; //Enable serial pins
CREN = 1; //Enable continuous receive
SREN = 0;
TX9  = ninebits?1:0;    /* 8- or 9-bit transmission */
RX9  = ninebits?1:0;    /* 8- or 9-bit reception */

PEIE = 1; //Enable external interrupt
GIE = 1; //Enable global interrupt

I have simplified my interrupt to turning on a light:

extern interrupt isr(void)
{
    RB5 = 1;
}

But it's not triggering. The project is reading a barcode scanner over serial and processing the barcode. Can anyone offer some assistance?

EDIT

Ok since you don't seem to understand. I'm going to post the actual routines:

void initialize()
{
    CMCON = 0x07;           //16F627/8 spcial function reg (RAx is port)
    CCP1CON = 0b00000000;   //Capt/Comp/PWM off

    OPTION_REG = 0b00000000;

    T1CON = 0;
    INTCON = 0;
    PIR1 = 0;
    GIE = 0;
    PEIE = 0;
    PIE1 = 0;

    sci_Init(BAUDRATE ,SCI_EIGHT);// Baud set and Bit set

    TMR0 = 1000;
    T0IE = 0;
    PEIE = 1; //Enable external interrupt
    GIE = 1; //Enable global interrupt

    //Set inputs to input
    SetButtons();

    //Set relays to output
    SetRelays();

    TRISB5 = 0;

    LEDStatus = 0;
}

unsigned char sci_Init(unsigned long int baud, unsigned char ninebits)
{
    int X;
    unsigned long tmp;

    /* calculate and set baud rate register */
    /* for asynchronous mode */
    tmp = 16UL * baud;
    X = (int)(FOSC/tmp) - 1;
    if((X>255) || (X<0))
    {
        tmp = 64UL * baud;
        X = (int)(FOSC/tmp) - 1;
        if((X>255) || (X<0))
        {
            return 1;   /* panic - baud rate unobtainable */
        }
        else
            BRGH = 0;   /* low baud rate */
    }
    else
        BRGH = 1;   /* high baud rate */
    SPBRG = X;  /* set the baud rate */

    SYNC = 0; //Async
    TXEN = 0; //Disable transmit
    TXIE = 0; //Disable transmit interrupt
    RCIE = 1; //Enable Receive interrupt
    SPEN = 1; //Enable serial pins
    CREN = 1; //Enable continuous receive
    SREN = 0;
    TX9  = ninebits?1:0;    /* 8- or 9-bit transmission */
    RX9  = ninebits?1:0;    /* 8- or 9-bit reception */

    rxBuffIndex = 0;
    rxBuffRead = 0;

    return 1;
}

void sci_LoadBuffer(void)
{
    rxBuffer[rxBuffIndex] = RCREG;

    rxBuffIndex = ++rxBuffIndex % MAXBUFFER;
}

unsigned char sci_ReadBuffer()
{
    unsigned char byte;

    do
    {
        byte = rxBuffer[rxBuffRead];
    }while( byte == 0 ); //Block until valid data

    rxBuffer[rxBuffRead] = 0;
    rxBuffRead = (++rxBuffRead) % MAXBUFFER;

    return byte;
}

void interrupt isr(void)
{
    if(RCIF) sci_LoadBuffer();
    LEDStatus = 1;
}

I know that's not EVERYTHING but that should be enough to diagnose why the interrupts aren't triggering. THAT'S ALL I NEED! Triggering the interrupts.

I'm using MPLab with Hi-Tech C Compiler. Which from the manual automatically saves state and restores it when entering/exiting the interrupt.

Best Answer

TRISB1 needs to be set to 1 to configure RB1 (RX) as an input. I'm not sure what the default is, so it may be ok.

You need to clear the receive interrupt flag (RCIF) by reading the receive register (RCREG). In addition, since the receive register is doubled-buffered, you may need to read it more than once.

So your interrupt routine needs to look more like this:

extern interrupt isr(void)
{
    while (RCIF)
    {
        char ch;

        RB5 = 1;
        ch = RCREG;    // normally would go into an array and increment a counter
    }
}

I don't know if that is your only problem, since you indicate you are not getting into the interrupt routine at all. But the above is the correct way to read the characters out of the receive buffer.

======================================

EDIT:

Don't know if this will help or not, but in this post, before enabling interrupts, the code clears out the FIFO first. (Their code also clears out the RCIF flag, but since it is readonly on your chip, that isn't needed.)

ch = RCREG;    // clear FIFO  
ch = RCREG;
ch = RCREG;

// then enable interruupts ...