Background
I was wondering if using ticker
interrupts could interfere with hardware interrupts triggered by a button press.
Example
Imagine I would like to use these two types of interrupts:
- a
ticker
timer to update a progress bar on a small display everyn
second - a
hardware interrupt
that starts/stops the process whose progress is displayed if the user presses a button
Important: Both interrupts set shared global volatile
flags.
Main question
Would it be possible for the ticker
interrupt to occur during a button induced interrupt and as a result for the program to end up in a state where the global flags are set contradictorily?
More specific questions
Does a hardware and a software interrupt have the same 'rank'?
If they occured at the same time, would the interrupt request occurring slightly later (but still overlapping with the first one) be ignored, or just put into a queue and execute straight after the first interrupt has finished? In this case, the flags would be set in an unexpected manner.
Can I disable one type of the interrupts inside the other type's ISR - i.e. ignore it?
I hope the problem statement is clear enough even without a code example.
I'mm assuming you are using an AVR.
When an interrupt fires, other interrupts are disabled while the interrupt routine is running. So any interrupts that occur in this time simply get flagged. When the interrupt routine returns, the global interrupt flag is re-enabled and any polled interrupts can then fire one at a time.
You can manually enable the global interrupts inside the routine for critical things that must run, but are disabled by default.
EDIT:
You can clear the pending interrupt, however you'll have to read the datasheet for your Arduino's AVR. You need to find the register for the external interrupt.
For example, on an atmega328p, external interrupt 0 can be cleared by setting its flag bit to 1:
EIFR |= (1 << INTF2);
EIFR
= External Interrupt Flag RegisterINTF2
= Bit 0 – INTF0: External Interrupt Flag 0However, it may be far simpler to poll the button in your
loop()
function. Or at best, simply set a flag for you to act upon back in theloop()
function. There you would be able to decide if you want to react or ignore to the interruptThere is the issue of having your interrupts far too large. If you use timing, or require accuracy, this could be affected by a large amount over time. As the interrupt queue length is only 1 deep some interrupts could be lost. And the interrupt which powers
millis()
µs()
runs multiple times per millisecond, so a bulky interrupt could end up slowing down time.Also do you have any debouncing code or hardware?
If not, the interrupt handling the button could be run multiple times on a single press.