Stm32 Evento e interrupciones

18

Comencé a estudiar las interrupciones en stm32 específicamente en el tablero de descubrimiento stm32f4. Encontré este ejemplo en el que tiene que presionar el botón para iniciar la interrupción y presionarlo nuevamente para detenerla.

En esta línea: EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt tenemos que elegir el modo de interrupción o el modo de evento. Lo cambié al modo de evento pero no parece funcionar. Así que salí con la conclusión de que el controlador se ejecuta solo con interrupciones.

¿Por qué usamos Eventos en stm32 si no puede ejecutar algún código cuando suceden?

Aquí está el código:

        #include "stm32f4xx.h"
        #include "stm32f4xx_syscfg.h"
        #include "stm32f4xx_rcc.h"
        #include "stm32f4xx_gpio.h"
        #include "stm32f4xx_exti.h"
        #include "misc.h"



        EXTI_InitTypeDef   EXTI_InitStructure;

        void EXTILine0_Config(void);
        void LEDInit(void);


        void ExtInt(void)
        {

          LEDInit();

          /* Configure EXTI Line0 (connected to PA0 pin) in interrupt mode */
          EXTILine0_Config();

          /* Generate software interrupt: simulate a rising edge applied on EXTI0 line */
          EXTI_GenerateSWInterrupt(EXTI_Line0);

          while (1)
          {
          }
        }

        /**
          * @brief  Configures LED GPIO.
          * @param  None
          * @retval None
          */
        void LEDInit()
        {
          GPIO_InitTypeDef  GPIO_InitStructure;

          /* Enable the GPIO_LED Clock */
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

          /* Configure the GPIO_LED pin */
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
          GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
          GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_Init(GPIOD, &GPIO_InitStructure);
        }

        /**
          * @brief  Configures EXTI Line0 (connected to PA0 pin) in interrupt mode
          * @param  None
          * @retval None
          */
        void EXTILine0_Config(void)
        {

          GPIO_InitTypeDef   GPIO_InitStructure;
          NVIC_InitTypeDef   NVIC_InitStructure;

          /* Enable GPIOA clock */
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
          /* Enable SYSCFG clock */
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

          /* Configure PA0 pin as input floating */
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
          GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
          GPIO_Init(GPIOA, &GPIO_InitStructure);

          /* Connect EXTI Line0 to PA0 pin */
          SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

          /* Configure EXTI Line0 */
          EXTI_InitStructure.EXTI_Line = EXTI_Line0;
          EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
          EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
          EXTI_InitStructure.EXTI_LineCmd = ENABLE;
          EXTI_Init(&EXTI_InitStructure);

          /* Enable and set EXTI Line0 Interrupt to the lowest priority */
          NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);
        }

        /**
          * @brief  This function handles External line 0 interrupt request.
          * @param  None
          * @retval None
          */
        void EXTI0_IRQHandler(void)
        {
          if(EXTI_GetITStatus(EXTI_Line0) != RESET)
          {
            /* Toggle LED1 */
            GPIO_ToggleBits(GPIOD, GPIO_Pin_12);

            /* Clear the EXTI line 0 pending bit */
            EXTI_ClearITPendingBit(EXTI_Line0);
          }
        }

        /**
          * @}
          */

        /**
          * @}
          */

        /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

        int main(void)
        {

            while(1)
            {
            }
        }
    
pregunta ChiPlusPlus

1 respuesta

14

A veces, encontrar la respuesta a estas preguntas para un dispositivo ARM puede ser más difícil que los microcontroladores más simples porque la información a menudo se distribuye entre las guías de programación y familiares en lugar de incluirse en la hoja de datos. En este caso, la respuesta parece estar en la página 381 de RM0090 Manual de referencia :

  

El STM32F4xx puede manejar eventos externos o internos para activar el núcleo   (WFE). El evento de activación se puede generar mediante:

     
  • (He eliminado los detalles del modo de interrupción externa normal)

  •   
  • o la configuración de una línea EXTI externa o interna en el modo evento. Cuando se reanude la CPU   desde WFE, no es necesario borrar el bit pendiente de interrupción periférica o el NVIC   El bit pendiente del canal IRQ como bit pendiente correspondiente a la línea de evento no está establecido.

  •   

Parece que el propósito principal es habilitar activaciones sin generar una interrupción o tener que responder a interrupciones durante el funcionamiento normal.

No se menciona en esa guía y no estoy seguro de qué tan aplicable es a la arquitectura STM32, pero en algunos otros dispositivos, esquemas similares pueden ser útiles para detectar eventos rápidos sin generar una interrupción. Por ejemplo, puede tener una aplicación en la que es importante capturar que se ha producido un evento de microsegundos, pero no es necesario responder a ella rápidamente, así que solo puede marcar una bandera para ver si ocurrió.

Editar: (5/2018) A partir de hoy, el número de página del texto al que se hace referencia es la página 381 (anteriormente, página 377)

    
respondido por el PeterJ

Lea otras preguntas en las etiquetas

Comentarios Recientes

En la mayoría de las distribuciones de Linux, systemd procesa eventos de algunos procesos privilegiados como NetworkManager y temporizadores. Luego, los eventos se envían a otros procesos para hacer su trabajo, pero todo lo que sucede durante el ciclo de eventos está enhebrado. Comenzando con systemd (hasta IceWM, pero desde GDM, systemd también se ejecuta en dispositivos Skia con alta resolución). Systemd recibe todos los eventos del sistema. Systemcall + Events recibe mensajes adicionales para que el usuario... Lees verder