Ich experimentiere mit der STM32f4
Entdeckung und habe versucht, eine Verzögerung (basierend auf SYSTICK
) in einem EXTI_IRQ
Handler zu verwenden, aber ich habe herausgefunden, dass der Handler nicht EXTI
ausgelö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.
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.
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.)
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.
Benutzer3629249