I'm trying to use Timer1 to get fired once a certain event occurs (about 1ms after the event). Using the timer to get a periodic interrupt works fine, but the very first interrupt fires immediately, rather than after the time I want it.
#include <Arduino.h>
void setup() {
Serial.begin(115200);
Serial.println("start");
}
#define ENTRIES 5
long stack[ENTRIES+1];
int ctr = 0;
ISR(TIMER1_OVF_vect) {
cli();
TCNT1 = 50000;
// if (micros() - stack[0] < 500) return; // work around guard would skip stray 1st interrupt
stack[ctr++] = micros();
if (ctr > ENTRIES)
TIMSK1 &= ~(1 << TOIE1);
sei();
}
void loop() {
if (ctr > ENTRIES) {
for (int i = 0; i < ENTRIES-1; i++) {
Serial.print(i);
Serial.print(": ");
Serial.println(stack[i+1] - stack[i]);
}
ctr = 0;
}
if (!Serial.available()) return;
char c = Serial.read();
if (c == 't') {
Serial.println("testing");
stack[0] = micros();
ctr = 1;
cli();
TCNT1 = 64000; // tick in around 1ms
TCCR1A = 0;
TCCR1B = (1 << CS10); // no prescaler
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt
sei();
}
}
When you enter t on the console it enables the interrupt and - unexpectedly - the timer fires at once. The next one comes after 1ms. A sample output looks like
start
testing
0: 8
1: 980
2: 980
3: 980
testing
0: 8
1: 980
2: 980
3: 980
Uncommenting the guard yields
start
testing
0: 988
1: 972
2: 976
3: 976
How can I modify my code (except setting a guard in the beginning of the ISR) so it is triggered once AFTER 1ms.
TCNT1is an unsigned and will coerce literal numbers correctly. SoTCNT1 = 50000;works as well. – qwerty_so Dec 02 '17 at 22:57