#include #include #include volatile uint8_t overflows = 0; volatile uint8_t last_overflows = 0; volatile uint16_t timerval = 0; volatile uint8_t finished = 0; ISR(TIMER1_OVF_vect) { // om det nu skulle ta mer än 4 sekunder overflows ++; } ISR(INT0_vect) { // ok, vi har fått en ny puls - ett nytt varv // nettotid ca 10 CPU-cykler, 0,6 µs // timerval = TCNT1; // aktuellt värde i TIMER1 TCNT1 = 0; // redo till nästa varv, nollställ TIMER1 last_overflows = overflows; // bygga ut till en 24bit räknare overflows = 0; finished = 1; // vi har aktuell data } void init(void) // även känd som setup() { // TIMER1 i normal mode, 1/1024 prescaler // på ett 16 MHz system blir det steg på 64 µs // WGMxx = 0b0000 // CSxx = 0b101 // overflow interrupt enabled TCCR1A = (0 << WGM11) | (0 << WGM10); TCCR1B = (0 << WGM13) | (0 << WGM12) | (1 << CS12) | (0 << CS11) | (1 << CS10); TIMSK1 = (1 << TOIE1); // init interrupt on INT0-pin // assume RISING EGDE EICRA = (1 << ISC01) | (1 << ISC00); EIMSK = (1 << INT0); finished = 0; sei(); // enable global interrupts } int main(void) { uint32_t total_time; init(); while (1) { if (finished) // finns det trovärdig data? { finished = 0; // vi har hämtat data, förberedd för en ny hämtning // det här kan säkras genom att stoppa in i ett "atomic block" // för att undvika problem där en INTO-interrupt händer just när vi hantera de // globala variablerna ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { total_time = timerval + overflows << 16; } total_time = total_time * 64; // räkna om till µs // // gör vad du vill nu med total_time // } } }