Setting TIMSK1 immediately fires the ISR

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi guys,

 

I would like a timer to call an ISR roughly 130ms after enabling the timer. To do this, I have employed the code below, but unfortunately, the ISR fires immediately when I set the OCIE1A bit in TIMSK1. I'm not sure if this is intended behaviour, or whether I've got something rather wrong. I'm using a '328p, and shamelessly it's Arduino code too.

 

Any tips would be greatly appreciated, thanks!

 

void setup() {

  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  OCR1A = 2000;
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS12 and CS10 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);
  // enable timer compare interrupt
  //TIMSK1 |= (1 << OCIE1A);

  pinMode(A2, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(3000);
  digitalWrite(A2,HIGH);

  TCNT1=0;

  TIMSK1 |= (1 << OCIE1A);
}

ISR(TIMER1_COMPA_vect){

    digitalWrite(A2,LOW);

  //stop
    TIMSK1=0;
}

 

* Arduino code, so moved to Arduino forum. Moderator *

This topic has a solution.
Last Edited: Mon. Mar 20, 2017 - 11:12 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

* Arduino code, so moved to Arduino forum. Moderator *

 

I thought it more relevant in the xAVR forum since it's an AVR problem rather than Arduino - I'm just using the Arduino libs to save time with reading/writing to ports smiley

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try clearing the interrupt flag before enabling the interrupt, as follows (a direct write, not using logical OR):

 

TIFR1 = (1<<OCF1A);

 

Last Edited: Mon. Mar 20, 2017 - 04:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's brilliant, thank you so much - I've been trying to fix this for hours! laugh

Last Edited: Mon. Mar 20, 2017 - 04:05 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Be warned that Arduino usually uses timer1 for its own purposes so I think that as soon as you take over things like delay() and millis() are going to stop working as intended.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Be warned that Arduino usually uses timer1 for its own purposes so I think that as soon as you take over things like delay() and millis() are going to stop working as intended.

I'm fairly sure Arduino uses timer0 for millis() updates?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah yes, I see what you mean...

 

https://github.com/arduino/Ardui...

 

Seems timer 0 is for the delays etc while timer 1+ are configured as PWM presumably for analogWrite() so as long as you don't plan to use that you should be OK.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Ah yes, I see what you mean...

 

https://github.com/arduino/Ardui...

 

Seems timer 0 is for the delays etc while timer 1+ are configured as PWM presumably for analogWrite() so as long as you don't plan to use that you should be OK.

Good point. I do use PWM so I may need to change to Timer2. If I only use one pin of timer1's output compare output, I.e. OC1B, presumably the PWM output would still work on the pin attached to OC1A? I realise I may have to write my own analogWrite() since the built-in one won't know about my ISR.

Seems this is more an Arduino question after all!