Evento Stm32 e interrupções


17

Comecei a estudar interrupções no stm32, especificamente na placa de descoberta stm32f4. Encontrei este exemplo em que você deve pressionar o botão para iniciar a interrupção e pressionar novamente para interrompê-lo.

Nesta linha: EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt, temos que escolher o modo de interrupção ou o modo de evento. Eu mudei para o modo de evento, mas ele não parece funcionar. Então, cheguei à conclusão de que o manipulador é executado com apenas interrupções.

Por que usamos os Eventos no stm32 se você não pode executar algum código quando eles acontecem?

Aqui está o 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)
            {
            }
        }

Respostas:


14

Às vezes, encontrar a resposta para essas perguntas para um dispositivo ARM pode ser mais difícil do que os microcontroladores mais simples, porque as informações geralmente estão espalhadas pela família e pelos guias de programação, em vez de incluídas na folha de dados. Nesse caso, a resposta parece estar na página 381 do manual de referência do RM0090 :

O STM32F4xx é capaz de lidar com eventos externos ou internos para ativar o núcleo (WFE). O evento de ativação pode ser gerado por:

  • (Eu removi os detalhes normais do modo de interrupção externa)

  • ou configurando uma linha EXTI externa ou interna no modo de evento. Quando a CPU sai do WFE, não é necessário limpar o bit pendente de interrupção periférica ou o bit pendente do canal NVIC IRQ, pois o bit pendente correspondente à linha de eventos não está definido.

Portanto, parece que o principal objetivo é ativar as ativações sem gerar uma interrupção ou ter que responder a interrupções durante a operação normal.

Isso não é mencionado nesse guia e não tenho certeza de quão aplicável é a arquitetura do STM32, mas em alguns outros dispositivos esquemas semelhantes podem ser úteis para capturar eventos rápidos sem gerar uma interrupção. Por exemplo, você pode ter um aplicativo em que é importante capturar que ocorreu um evento de microssegundo, mas não há necessidade de respondê-lo rapidamente, basta verificar um sinalizador para ver se ele ocorreu.

Edit: (5/2018) A partir de hoje, o número da página do texto referenciado é a página 381 (anteriormente, página 377)


11
Sim, nos PICs, parece que muito do que faço em uma interrupção é definido como sinalizadores. Em Cortex, a maioria dessas bandeiras prepare-se sem ter que interromper, então eu uso menos interrupções
Scott Seidman
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.