3
votes

I have an ATMega8515 and I am trying to setup a timer interrupt so that if a process takes too long it will shut off.

I setup the timer with:

void init_software_interupt(double time)
{
    OCR1A = time;
    TCCR1A = 0;
    TCCR1B = 0;
    TCCR1B |= (1 << WGM12);
    TCCR1B |= (1<<CS10);
    TCCR1B |= (1<<CS12);
    TIMSK |= (1 << OCIE1A);
    sei();
}

This works great. I calculated a clock second to be 7812 for an 8MHz clock and it works exactly as expect printing stuff once every second:

//Timer Interupt
int seconds = 0;
ISR(TIMER1_COMPA_vect){
    seconds++;
    printf("in timer overflow: %d seconds have passed\r\n",seconds);
    in_progress = FALSE;
}

The problem is that I might call the function unlock_door() 750ms into the 1 second overflow count and it would only allow the operation to take 250ms which isn't long enough.

I've tried to just set the output compare register before I call the function but it doesn't seem to have an affect:

OCR1A = 7812;
unlock_door();

But it doesn't change the current overflow.

How can I reset the overflow timer before I call a function to ensure it will take 1 second?

1
why don't use a watchdog timer? - phuclv

1 Answers

3
votes

It looks like you're using the compare interrupt, not the overflow interrupt. OCR1A stores the value that the counter is being compared to, and I believe that TCNT1 stores the actual timer value. Try:

TCNT1 = 0;
unlock_door();

Here's a good article on AVR timers, by the way. It's called "The Newbie's Guide to AVR Timers", but it works really well as a reference as well.