I am experimenting with the STM32f4 discovery and i tried to use a delay (based on SYSTICK) in an EXTI_IRQ handler but i figured out that while the EXTI handler is triggered the the systick handler doesn't trigger , here's my code :

extern volatile int del ;
void EXTI0_IRQHandler(void) {

  if (EXTI_GetITStatus(EXTI_Line0) != RESET ) {
        /* Do your stuff when PD0 is changed */
         del=1000 ;
       //do something 

       /* Clear interrupt flag */

And the systick handler :

void SysTick_Handler(void)
  if (del--)

So how can i solve this problem .

  • \$\begingroup\$ on most CPUs, interrupts have an order of precedence. A higher precedence interrupt will mask a lower precedence interrupt while the higher precedence interrupt is being handled. \$\endgroup\$ – user3629249 Mar 25 '16 at 19:54

You can, if your processor allows it (it should, since I believe all of that series are Cortex M4 based), set the Systick Interrupt to a higher priority than the other interrupts and then find out if you can make your compiler/processor not turn off interrupts globally while processing an interrupt.

That is, if you want to have delays in your interrupts.

Hint: You shouldn't want that.

Interrupts are meant to run efficiently and quickly to handle important events that are critical. If something needs a delay beyond a couple of ASM("__volatile__ NOP\n NOP\n NOP\n")'s, it's probably not something you want in your interrupt.

If you have a "heavy task" that gets triggered by an interrupt it's much neater to write:

uint32_t taskFlags;  // semafore register, can also be any other data type that fits your flags (1ul --> uint32_t or larger!)
#define HANDLE_MY_INTERRUPT_STUFF    (1ul<<0) // Define a flag for interrupt things.

void main(void) {
    while(1) {
        if(taskFlags & HANDLE_MY_INTERRUPT_STUFF) { // Check the flag
            // Do your interrupt stuff
            // Allowed to have many delays and other weird stuff

            taskFlags &= ~HANDLE_MY_INTERRUPT_STUFF; // Clear the flag.

InterruptHandler(void) {
    taskFlags |= HANDLE_MY_INTERRUPT_STUFF;  // set the flag

And now suddenly all that heavy processing gets done in the main loop, where it can be interrupted and all and won't harm any other time-critical things. But only triggered by the interrupt source, through the flags.

Although through the flags you will of course risk a slight variable delay in execution, it's always a balancing act.

Late addition:

Between processor types the delay will usually be between 4 and 40 clock cycles + average other interrupt code execution, so at a couple MHz using a 10ms delay will usually already marginalise that delay and its variation.)

  • \$\begingroup\$ but what if it's the case when you need to denounce a button ( the case of interruption triggered with push button ) with a delay i know i can make delay with a for loop but it's a bad solution . \$\endgroup\$ – starter Mar 24 '16 at 1:21
  • 1
    \$\begingroup\$ @starter see the second part. Anything you do inside the interrupt can be done in the main with a flag. It's that simple. \$\endgroup\$ – Asmyldof Mar 24 '16 at 1:58
  • \$\begingroup\$ thank you that was helpful , i was over complicating life . \$\endgroup\$ – starter Mar 24 '16 at 7:28

This is the simplest solution to do:

extern __IO uint32_t TimmingDelay;

void Delay(__IO uint32_t time)
  TimmingDelay = time;
  while(TimmingDelay != 0);

This is in stm32f4xx_it.c:

void SysTick_Handler(void)
  if(TimmingDelay != 0)
    TimmingDelay --;

In main don't forget to add this line:


and then use Delay("AddDelayHere"); and spam all over your code.

  • \$\begingroup\$ This isn't guaranteed to solve the interrupt conflict \$\endgroup\$ – Asmyldof Mar 24 '16 at 0:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.