问:如何在Arduino上启动和停止中断计时器?

时间:2016-04-24 17:06:36

标签: timer arduino interrupt

我试图停止并在他计算500后再次恢复我在Arduino上的中断计时器。 因此,中断计时器计数到500,然后延迟几秒钟,然后再次恢复中断计时器

这是我的代码,我可以停止中断,但不知道如何再次延迟和恢复计时器

#define ledPin 13
int count=0;
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
cli();//stop interrupts
//set timer0 interrupt at 2kHz
  TCCR1A = 0;// set entire TCCR0A register to 0
  TCCR1B = 0;// same for TCCR0B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 2khz increments
  OCR1A = 124;// = (16*10^6) / (2000*64) - 1 (must be <256)
  // turn on CTC mode
  TCCR1A |= (1 << WGM01);
  // Set CS01 and CS00 bits for 64 prescaler
  TCCR1B |= (1 << CS01) | (1 << CS00);   
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
sei();
}

ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine
{
count++;
if(count%2==0)digitalWrite(ledPin,HIGH);
if(count%2==1)digitalWrite(ledPin,LOW);
if(count>=500)
{
  count=0;
  TCCR1B=0;
  digitalWrite(ledPin,LOW);
  //TCCR1B |= (1 << CS01) | (1 << CS00); 
}

}

void loop()
{
// your program here...

Serial.println(count);
delay(1000);

}

void berhenti()
{
cli();//stop interrupts
digitalWrite(ledPin,LOW);
count=0;
delay(3000);
sei(); 
}

1 个答案:

答案 0 :(得分:0)

您可以使用millis()功能计算所需的时间。

#define ledPin 13
int count=0;

// A boolean to know if the timer is stopped or not.
// You can use the TIMSK1 bit, but I prefer a seperate variable.
boolean  timerStopped = false; 

// Time when the timer stopped.
long timerStoppedTime = 0;

// Your delay in milliseconds.
// You can use a macro here as well.
long timerStoppedDelay = 1000; 

// I'll explain this variable in the answer.
boolean takeTimeTimerStopped = true; 

void setup()
{
     // I haven't change this function.
}

ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine
{
    count++;
    if(count%2==0)digitalWrite(ledPin,HIGH);
    if(count%2==1)digitalWrite(ledPin,LOW);
    if(count>=500)
    {
        count=0;
        TCCR1B=0;
        digitalWrite(ledPin,LOW);
        TIMSK1 |= (0 << OCIE1A); // deactivate timer's interrupt.
        timerStopped = true;
    }

}

void loop()
{
    // your program here...

    Serial.println(count);
    delay(1000);

    if(timerStopped)
    {
        if(takeTimeTimerStopped)
        {
            timerStoppedTime = millis();
            takeTimeTimerStopped = false;
        }
        if((millis() - timerStoppedTime) >= timerStoppedDelay)
        {
            TIMSK1 |= (1 << OCIE1A); // reactivate the timer.
            timerStopped = false;
            takeTimeTimerStopped = true;
        }
    }

 }

每次输入takeTimeTimerStopped语句时,您需要timerStoppedTime布尔值才能更改if(timerStopped)。 避免这种丑陋的东西的合理方法是花时间在ISR中。 但millis()它自己使用timer0中断进行计数,不应在http://www.arduino.cc/en/Reference/AttachInterrupt

中描述的ISR中调用

请注意,dealy()功能中对loop的每次调用都会进一步延迟重新启动计时器的时间。你也需要考虑这一点。