问题描述
我是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上的快速向下毛刺?