#include <avr/io.h>
#include <util/atomic.h>
#include <avr/interrupt.h>
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
//
}
}
}
Comments