pic定时器2中断触发太快

时间:2015-09-26 10:14:48

标签: timer interrupt pic

我使用mplab代码配置器为定时器(timer2)生成代码。在组合中,我选择计时器周期的最长时间。所以我在T2OUTPS(1111)中使用1:16的后置测试器,在T2CKPS(1x)中使用16的预分频器 这个时期应该是几秒钟,但它会每半秒触发一次(aprox)。我不明白这个问题是什么,因为我给前后分配器的价值并不重要,期间是相同的

这是相关代码。这是我初始化计时器的方式:

void TMR2_Initialize(void) {
  // Set TMR2 to the options selected in the User Interface

  T2CON = 0b01111011;
  //T2CON = 0x3A;
  //T2CON.T2OUTPS = 0b0000;


  // PR2 255; 
  PR2 = 0xFF;

  // TMR2 0x0; 
  TMR2 = 0x00;

  // Clearing IF flag before enabling the interrupt.
  PIR1bits.TMR2IF = 0;

  // Enabling TMR2 interrupt.
  PIE1bits.TMR2IE = 1;

  // Start TMR2
  TMR2_StartTimer();
}

void TMR2_StartTimer(void) {
   // Start the Timer by writing to TMRxON bit
   T2CONbits.TMR2ON = 1;
}

这就是我处理中断的方式:

void interrupt SYS_InterruptHigh(void)
{
  if (PIE1bits.TMR2IE == 1 && PIR1bits.TMR2IF == 1) {
      TMR2_ISR();
  }   

......


void TMR2_ISR(void) {

  // clear the TMR2 interrupt flag
  PIR1bits.TMR2IF = 0;


  if (colorUpdate%4 == 1)
  {
      LED_Color(0xFFFF,0x0000,0xFFFF);
  }
  else if (colorUpdate%4 == 2)
  {
      LED_Color(0x0000,0xFFFF,0xFFFF);
  }
  else if (colorUpdate%4 == 3)
  {
      LED_Color(0xFFFF,0xFFFF,0x0000);    
  }
  else if (colorUpdate%4 == 0)
  {
       LED_Color(0x0000,0xFFFF,0x0000);   
  }

  colorUpdate++;
  if (colorUpdate>1000)
      colorUpdate = 0;

  LED_UpdateImage();

  LATCbits.LATC6 = 1;

  LATCbits.LATC6 = 0;

}

2 个答案:

答案 0 :(得分:0)

TMR2必须在中断程序中重新加载。

此外,最好避免中断服务程序中的函数调用开销。做必要的最低限度。如果可能,如果您可以容忍时间上的微小偏差,请发出外部任务信号以进行实际工作。

答案 1 :(得分:0)

这是作为评论开始的,但我的空间不足,所以我发帖作为答案。

如果f_OSC为16 MHz或f_OSC为16 MHz x 3(PLL)/ CPUDIV,OP的最新评论并不清楚 - 在这种情况下,最小值/最大值f_OSC为分别为8/24 MHz。

但是让我们使用f_OSC = 16 MHz。据我所知,Timer2时钟源为f_OSC/4 = 4 MHz,后置和前置缩放器的组合效果为/ 256,因此TMR2以15625 Hz(@ 16 MHz f_OSC)递增。当PR2为255时,我希望TMR2IF在每255/15625 = 0.01632 s(~60 Hz)时触发。在f_OSC = 8 MHz,这将是每0.03264秒(~30赫兹),f_OSC = 24 MHz(16 MHz x 3/2),这将是每0.01088秒(~90赫兹)

基于此,我认为你对中断间隔的期望可能是基于一个不正确的前提,因为它与你的f_OSC相差甚远。

即使观察到的中断间隔也比上面计算的要长得多。 我怀疑这是由于以下原因之一:

  1. 中断是饥饿的 - 它或其他优先级较高的任务需要很长时间才能执行TMR2_ISR()只执行大约每半秒。
  2. pin C6脉冲持续时间很短,您无法使用示波器/ LA /您使用的任何测试设备捕获所有脉冲。
  3. 我建议您进行以下一项或两项调查:

    1. LATCbits.LATC6 = 1;移到TMR2_ISR()的顶部 - 这样脉冲的高持续时间将指示ISR的执行时间,并且信号的频率将告诉您多长时间ISR被执行。如果脉冲持续时间太短而无法捕获所有脉冲持续时间,这也应该更容易发现。

    2. 在您现在具有相同设置的程序中测试您的定时器设置,但定时器2 ISR只做两件事 - 重置TMR2IF和切换针C6(切换相反)脉冲也更容易捕获 - 但当然你的中断频率是C6上方波频率的两倍)