Systick-Unterbrechung wird nicht ausgelöst, wenn ein anderer Interrupt behandelt wird

Ich experimentiere mit der STM32f4Entdeckung und habe versucht, eine Verzögerung (basierend auf SYSTICK) in einem EXTI_IRQHandler zu verwenden, aber ich habe herausgefunden, dass der Handler nicht EXTIausgelöst wird, während der Handler ausgelöst wird . Hier ist mein Code:systick

extern volatile int del ;
void EXTI0_IRQHandler(void) {

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

       /* Clear interrupt flag */
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
  }

Und der Systick-Handler:

void SysTick_Handler(void)
{
  if (del--)
 ;
}

Also wie kann ich dieses Problem lösen.

Auf den meisten CPUs haben Interrupts eine Rangfolge. Eine Unterbrechung mit höherer Priorität maskiert eine Unterbrechung mit niedrigerer Priorität, während die Unterbrechung mit höherer Priorität behandelt wird.

Antworten (2)

Sie können, wenn Ihr Prozessor es zulässt (es sollte, da ich glaube, dass alle diese Serien Cortex M4-basiert sind), den Systick-Interrupt auf eine höhere Priorität als die anderen Interrupts setzen und dann herausfinden, ob Sie Ihren Compiler/Prozessor nicht machen können Schalten Sie Interrupts global aus, während Sie einen Interrupt verarbeiten.

Das heißt, wenn Sie Verzögerungen in Ihren Interrupts haben möchten.

Hinweis: Das sollten Sie nicht wollen.

Interrupts sollen effizient und schnell ausgeführt werden, um wichtige Ereignisse zu verarbeiten, die kritisch sind. Wenn etwas eine Verzögerung von mehr als ein paar benötigt ASM("__volatile__ NOP\n NOP\n NOP\n"), ist es wahrscheinlich nicht etwas, was Sie in Ihrem Interrupt wollen.

Wenn Sie eine "schwere Aufgabe" haben, die durch einen Interrupt ausgelöst wird, ist es viel sauberer zu schreiben:

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
}

Und jetzt wird plötzlich all diese schwere Verarbeitung in der Hauptschleife erledigt, wo sie unterbrochen werden kann und alle anderen zeitkritischen Dinge nicht beeinträchtigt werden. Aber nur ausgelöst durch die Interrupt-Quelle, durch die Flags.

Obwohl Sie durch die Flaggen natürlich eine leichte variable Verzögerung in der Ausführung riskieren, ist es immer ein Balanceakt.

Nachtrag:

Zwischen den Prozessortypen liegt die Verzögerung normalerweise zwischen 4 und 40 Taktzyklen + durchschnittlicher Ausführung anderer Interrupt-Codes, sodass bei ein paar MHz mit einer Verzögerung von 10 ms diese Verzögerung und ihre Variation normalerweise bereits marginal sind.)

aber was ist, wenn es der Fall ist, wenn Sie eine Taste (im Fall einer mit der Taste ausgelösten Unterbrechung) mit einer Verzögerung denunzieren müssen? Ich weiß, dass ich mit einer for-Schleife eine Verzögerung machen kann, aber es ist eine schlechte Lösung.
@starter siehe den zweiten Teil. Alles, was Sie innerhalb des Interrupts tun, kann im Main mit einem Flag ausgeführt werden. So einfach ist das .
Danke, das war hilfreich, ich war es zu kompliziert, das Leben zu erschweren.

Dies ist die einfachste Lösung:

extern __IO uint32_t TimmingDelay;

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

Dies ist in stm32f4xx_it.c:

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

Vergessen Sie im Wesentlichen nicht, diese Zeile hinzuzufügen:

  SysTick_Config(SystemCoreClock/1000000);

und verwenden Sie dann Delay("AddDelayHere"); und Spam über Ihren gesamten Code.

Dies löst den Interrupt-Konflikt nicht garantiert