Two functions in the high priority interrupt

cinterruptsmicrocontrollerpic

I'm using the PIC18F46k22 mcu and I'm using two function in my high priority interrupt routine:

#pragma code
#pragma code My_HiPrio_Int=0x0008   
#pragma code
#pragma interrupt chk_isr

#pragma code
void My_HiPrio_Int(void)
{
    _asm
        GOTO chk_isr
    _endasm
}

void chk_isr(void)      /*Serial Interrupt*/
{   
    INTCONbits.GIE = 0;

    if(INTCONbits.TMR0IF==1)   //Timer routine
        Timer0_ISR();

    if(PIR1bits.RC1IF)     //RS485 receiver 
        RC_ISR();

    INTCONbits.GIE = 1;


}


void Timer0_ISR(void)
{
    nTick0++;

    if(pSet == 0) nTickSetPress++;
    else nTickSetPress = 0;

    if(pPlus == 0) nTickPlusPress++;
    else nTickPlusPress = 0;

    if(pMinus == 0) nTickMinusPress++;
    else nTickMinusPress = 0;

    if(pShift == 0) nTickShfPress++;
    else nTickShfPress = 0;

    if(pCountPlus == 0) nTickCount++;
    else nTickCount = 0;

    if(pReset == 0) nTickResetPress++;
    else nTickResetPress = 0;

    if(bCdlyStart == 1) nCdlyCount++;
    if(nCdlyCount >= nTickCdly) bCdlyStart = 0;

    if(bDisplayTime == 1) nDisplayTimeCount++;

    if(bBlinkDigitFast == 1) nTickBlinkFast++;

    TMR0H = TMR0HValue;
    TMR0L = TMR0LValue;
    INTCONbits.TMR0IF = 0;
}


void RC_ISR(void)       
{
    rxbuf485 = RCREG1;

    if (rxbuf485 == 0)
    {
        return;
    }

    if (rxbuf485 == TOKEN)
    {
        b485RxToken = 1;
        return;
    }

    if (b485RxComplete) return;

    if (!b485SOH)
    {
        if (rxbuf485 != SOH) return;
        b485SOH = 1;
        n485RxDataPos = 0;
        b485RxComplete = 0;
        memset (RS485RXDATA, 0, sizeof(RS485RXDATA));
        return;
    }   
    else if (rxbuf485 == EOT)
    {
        b485SOH = 0;
        b485RxComplete = 1;
        return;
    }
    if (n485RxDataPos == 50) 
        n485RxDataPos = 50;

    if (n485RxDataPos>=RS485RXSIZE) 
        n485RxDataPos--;

    RS485RXDATA[n485RxDataPos++] = rxbuf485;
    return;

}

void Timer0Init(void)
{
    T0CON = 0x07;
    TMR0H = TMR0HValue;
    TMR0L = TMR0LValue;
    T0CONbits.TMR0ON = 1;
    INTCONbits.TMR0IE = 1;
    nTick0 = 0; 
    nTickSetPress = 0;
    nTickResetPress = 0;
    nTickCdly = 0; 
    nTickBlinkFast = 0;
}

void RS485Init(void)
{
    TRISCbits.TRISC7=1;     // RX
    TRISCbits.TRISC6=0;     // TX

    TXSTA1 = 0x00;          
    RCSTA1 = 0x90;      
    SPBRG1 = 30;            
    BAUDCON1 = 0x00;    
    PIE1bits.RC1IE = 1;      
    TRISCbits.TRISC3 = 0;
    p485 = 0;               

    memset (RS485RXDATA, 0, sizeof(RS485RXDATA));   
}

Can two routine be done in a high priority interrupt? Will there be any problem in long term?
This is because I'm trying to find out why my device always hang after running a few days…

Best Answer

There is much silliness here:

  1. Your interrupt routine is just jumping into another routine instead of executing directly. You may need to do something like that if you are also using low priority interrupts, but this doesn't seem to be the case.

  2. What's with setting GIE to 0 in the interrupt routine? You need to actually read the datasheet.

  3. Even worse, you are setting GIE to 1 near the end of the second interrupt routine. I could try to explain why you shouldn't do that, but you need to read the datasheet anyway, so you can discover for yourself why this is a dumb idea.

  4. By being too clever by a half, as the British like to say, you have defeated the compiler's means of properly turning on interrupts again at the end of the interrupt service routine. Put another way, you are no longer running a RETFIE instruction.

  5. This whole thing could have been done much more easily in assembler, and then maybe you'd see how the interrupt code is messed up the way it is now. Unlike on large systems with many levels of abstraction, on small resource limited systems using a compiler doesn't alleviate the need to actually understand what is happening at the machine instruction level.

  6. Messing with machine details like interrupts absolutely requires reading the datasheet.