Why my code on PIC18F XC8 causes few times per second interrupt extension?

475 views Asked by At

I am new in PIC processors programming and I need a little help. I'm using PIC18F8680, programming in C with XC8 compiler in MPLAB X IDE v5.35.

I have two interrupts, high priority on timer 0 (5 kHz) and low priority on timer 1 (200 Hz). In high priority int, I call function, that calls another function, where I do AD input conversion.

__interrupt(high_priority) void ISR0(void)
{    
    if((INTCONbits.TMR0IE == 1) && (INTCONbits.TMR0IF == 1)) 
    {
        INT_TMR0_ACK
        cntTMR0++;
      
        if (address== MOD_PPP)
        {
            doSomething ();           
        }       
    }
} /* ISR0() */

__interrupt(low_priority) void ISR1(void)
{       
    if((PIE1bits.TMR1IE == 1) && (PIR1bits.TMR1IF == 1)) 
    {
        INT_TMR1_ACK
        cntTMR1++;
               
        if (address== MOD_PPP)
        {     
            doSomethingElse (); 
        } 
    }
} /* ISR1() */

void doSomething()
{
    UrealS = convertUpp (readExtAD (1), 0);    // readExtAD returns raw value from 14 bit +-10 V AD in U16 format (always >= 0)    
}

U16 convertUpp (U32 input, U8 channel)
{
    LATJ |= 0x02;

    // offset check (using current loop 4-20 mA with 5 ohm input rezistor amplified by 10x)
    U16 offset = 160;  
    if (input<= offset)                                                        
        input = 0;
    else 
        input-= offset;
        
    // filter
    analog [channel].sum -= analog [channel].mean;
    analog [channel].sum += input;
    analog [channel].mean = analog [channel].sum >> 6;
    input= analog [channel].mean;
        
    // conversion
    input *= 4375;
    input>>= 8;
    input>>= 4; 
 
    LATJ &= ~0x02;

    return input;
}

typedef struct
   {
   U32 sum;
   U16 mean;
   } sADC_PARAM;

sADC_PARAM analog [4];

Variable "address" is global and is set only once in init routine.

With toggling LATJ, I'm testing the function time length with oscilloscope. Problem is, I expect, it would looks like this Expected, but on oscilloscope I can see, that few times in second, it looks like this Real. I can't find any reason, why is one of x int cycle longer than others.

Do you see something I'm missing? Or, is the concept of measuring like this bad (and why)?

Thanks in advance.

PS: I translated code to english for bettter understanding, If you find any czech word, let me know, I translate it.

Edit: grammar, variable "address" description

1

There are 1 answers

2
EBlake On

I'm unsure if this is the source of your problems, but I note a few issues:

(1) Checking the values of TMR0IE and TMR0IF is unnecessary because the interrupt will be called only if both bits are set.

(2) By acknowledging the interrupt early, you open the opportunity for the interrupt to be triggered again before it has completed - your scope may not be fast enough to catch the glitch showing retriggering of the interrupt. It is generally better to acknowledge (clear the TMR0IF) at the end of the routine.

(3) It seems that your 5kHz interrupt is calling doSomething() at about 830Hz, under the control of the value in address. Could it be that stalled changes in the value of address (presumably a global variable) is causing several calls to doSomething() in a row, and once again your scope resolution is not seeing the fast downward glitches on LATJ.b2?