La interrupción de Systick no se dispara cuando se maneja otra interrupción

2

Estoy experimentando con el descubrimiento STM32f4 y traté de usar un retraso (basado en SYSTICK ) en un controlador EXTI_IRQ pero descubrí que mientras el controlador EXTI se activa el systick el controlador no se activa, aquí está mi código:

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);
    }
  }

Y el manejador de systick:

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

Entonces, ¿cómo puedo resolver este problema?

    
pregunta starter

2 respuestas

7

Usted puede, si su procesador lo permite (debería, ya que creo que todas las series están basadas en Cortex M4), configure la Interrupción de Systick con una prioridad más alta que las otras interrupciones y luego averigüe si puede hacer su compilador / el procesador no desactiva las interrupciones globalmente mientras procesa una interrupción.

Es decir, si quieres tener retrasos en tus interrupciones.

Sugerencia: no deberías querer eso.

Las interrupciones están diseñadas para ejecutarse de manera eficiente y rápida para manejar eventos importantes que son críticos. Si algo necesita un retraso más allá de un par de ASM("__volatile__ NOP\n NOP\n NOP\n") 's, probablemente no sea algo que quieras en tu interrupción.

Si tiene una "tarea pesada" que se desencadena por una interrupción, es mucho mejor escribir:

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
}

Y ahora, de repente, todo ese procesamiento pesado se realiza en el bucle principal, donde puede interrumpirse y todo lo demás, y no dañará ninguna otra cosa crítica en el tiempo. Pero solo se desencadena por la fuente de interrupción, a través de las banderas.

Aunque a través de las banderas, por supuesto, se arriesgará a un ligero retraso en la ejecución, siempre es un acto de equilibrio.

Adición tardía:

Entre los tipos de procesadores, el retraso generalmente estará entre 4 y 40 ciclos de reloj + el promedio de ejecución de otro código de interrupción, por lo que a un par de MHz con un retraso de 10 ms generalmente ya se eliminará ese retraso y su variación.)

    
respondido por el Asmyldof
0

Esta es la solución más sencilla de hacer:

extern __IO uint32_t TimmingDelay;

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

Esto está en stm32f4xx_it.c:

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

En main no olvides agregar esta línea:

  SysTick_Config(SystemCoreClock/1000000);

y luego use Delay ("AddDelayHere"); y spam en todo tu código.

    
respondido por el user45189

Lea otras preguntas en las etiquetas