Question on Delays & Interrupts

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

Hi.

I am using Codevision to write code for an ATMEGA8. I have a timer interrupt that occurs every 800uSec. This is working great and I have it to check the status of an input pin every interrupt. Easy enough...

I also have a function with a hard coded delay using Codevision's "delay_ms" function. I use delay_ms(128) for a 128 millisecond delay.

So for my question: During the delay function, when an interrupt occurs, will the delay break, process the interrupt, then continue with the delay? Or will the interrupt not happen during a delay_ms function?

I am seeing what looks like the pin not being check as often as I was hoping for and I thought the delay function built into codevision may be the cause.

Any help would be appreciated. Thanks!

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

If you don't disable the timer interrupt (globally or individually), it will temporarily break out of the delay function.

Actually I'm speaking generically here. Codevision's delay function could certainly disable interrupts, but that would be a very strange thing to do, IMHO.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

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

Thanks Zbaird. I didn't think the delay function would disable interrupts either.

By the way since I am on the topic...what happens if the processing in the Interrupt Service Routine takes more time than the actual interrupt timer? Meaning, an interrupt happens while you are in the ISR. Is it "good practice" to disable that interrupt while you are in the ISR?

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

Interrupts are automatically disabled when you service an interrupt, and enabled at the completion of the ISR. You are free to enable them within an ISR, but this is generally not recommended.

If an interrupt occurs while an ISR is being executed, the second interrupt will be serviced after the first ISR terminates. If two of the same type of interrupts occur, only one will be remembered, so you have a lost interrupt.

When you exit the ISR, if there are several pending interrupts to be serviced, they are done in their priority order (the order of the interrupt vectors).

The bottom line is, ISRs should be very short. Get in, do the work, and get out.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

Last Edited: Fri. Sep 12, 2008 - 02:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
By the way since I am on the topic...what happens if the processing in the Interrupt Service Routine takes more time than the actual interrupt timer? Meaning, an interrupt happens while you are in the ISR. Is it "good practice" to disable that interrupt while you are in the ISR?
Interrupts are automatically disabled whenever an ISR executes and re-enabled at the end. If the timer interrupt fires again while still in the ISR, the ISR will not be interrupted. Instead, as soon as the ISR finishes, it will be triggered again.

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

Silly idea but did you realise that 160 lots of 800us is 128ms ?

In other words, don't do a delay_ms() (it won't be accurate if it keeps getting interrupted anyway!) but in the 800us interrupt just increment a 'counter' variable then where you want the 128ms delay just do:

counter = 0;
while (counter<160);

and it will exit the while after 128ms.

For more efficient code (possibly) have the interrupt decrement rather than increment the counter variable and in the main line code:

counter = 160;
while (counter);

as it's "easier" to test for 0 than 160.

Cliff