为什么我在PIC18F XC8上的代码每秒导致几次中断扩展?

问题描述

我是PIC处理器编程的新手,需要一点帮助。我正在使用PIC18F8680,使用MPLAB X IDE v5.35中的XC8编译器在C中进行编程。

我有两个中断,定时器0的高优先级(5 kHz)和定时器1的低优先级(200 Hz)。在高优先级int中,我调用函数,该函数调用一个函数,在此我进行AD输入转换。

__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];

变量“地址”是全局的,并且在初始化例程中仅设置一次。

通过切换LATJ,我正在使用示波器测试功能时间长度。我希望问题看起来像这样Expected,但在示波器上我可以看到,每秒几秒钟,看起来像这样Real。我找不到任何原因,为什么x int周期之一比其他更长。

您看到我想念的东西吗?或者,像这样的测量概念不好(为什么)?

谢谢。

PS:为了更好地理解,我将代码翻译成英语,如果您发现任何捷克字,请告诉我,我将其翻译。

编辑:语法,变量“地址”描述

解决方法

我不确定这是否是您的问题的根源,但我注意到一些问题:

(1)不需要检查TMR0IE和TMR0IF的值,因为只有在两个位都置位时才会调用中断。

(2)通过及早确认中断,可以打开在中断完成之前再次触发中断的机会-您的示波器可能不够快,无法捕捉到显示中断重新触发的故障。通常最好在例程结束时确认(清除TMR0IF)。

(3)在地址值的控制下,您的5kHz中断似乎正在以830Hz的频率调用doSomething()。可能是address值(可能是全局变量)的停滞变化导致连续多次调用doSomething(),而您的范围解析再一次没有看到LATJ.b2上的快速向下毛刺?