【问题标题】:Weird behaviour of timer2 on ATmega328ATmega328 上 timer2 的奇怪行为
【发布时间】:2017-09-26 12:10:05
【问题描述】:

我目前正在编写一段代码,它应该等待比较器中断并在设定的时间后执行一些其他代码。现在,我认为在 CTC 模式下使用 Timer2 是一个好主意,以确保程序等待正确的时间并提出以下建议:

void setup(){
  ...
  // Set up the timer
  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2  = 0;
  OCR2A  = 255;                         // compare match register
  TCCR2A = (1 << WGM21);                // CTC mode
  TCCR2B = ((1 << CS22) | (1 << CS21)); // 256 prescaler
  TIMSK2 &= ~(1 << OCIE2A);             // disable interrupt
}

ISR(ANALOG_COMP_vect) {
  // switchTime is in µs, usual value: around 500µs
  // with a 16 Mhz crystal and a 256 prescale we need to devide
  // the switchTime by 16 (2^4)
  OCR2A = switchTime >> 4;
  TCNT2 = 0;                   // reset counter
  TIMSK2 |= (1 << OCIE2A);     // enable timer compare interrupt
}

ISR(TIMER2_COMPA_vect) {
  TIMSK2 &= ~(1 << OCIE2A);    // disable interrupt
  // do stuff
}

尴尬的是,它不起作用。 ISR 定时器在我们离开 ISR 比较器后立即被调用(我通过在两个例程中切换一个引脚并用示波器测量来检查这一点)。经过几个小时阅读数据表并随机更改代码后,我想出了一行代码来修复它:

 ISR(TIMER2_COMPA_vect) {
  TIMSK2 &= ~(1 << OCIE2A);    // disable interrupt
  OCR2A = 255;                 // <- apparently fixes all my problems
  // do stuff
}

我对此感到很困惑,因为在我们调用例程并停用中断之后,计时器的频率不应该是问题

现在我很高兴我找到了解决方案,但我想知道它为什么有效。通过随机插入代码知道如何钓鱼并意外钓到鱼。

【问题讨论】:

  • 我认为您错过了未决定时器中断的清除。 /* 清除挂起的中断 */ TIFR2 = (1
  • 很好,就是这样!你愿意回答吗?
  • 我已将评论移至答案

标签: c timer arduino interrupt atmega


【解决方案1】:

我认为您错过了未决计时器中断的清除。

ISR(TIMER2_COMPA_vect) {
   TIMSK2 &= ~(1 << OCIE2A);    // disable interrupt
   /* Clear pending interrupts */ 
   TIFR2 = (1 << TOV2) | (1 << OCF2A) | (1 << OCF2B);
   // do stuff
} 

【讨论】:

    猜你喜欢
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 2013-04-20
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多