Stm32 이벤트 및 인터럽트


17

stm32, 특히 stm32f4 디스커버리 보드에서 인터럽트를 연구하기 시작했습니다. 버튼을 눌러 인터럽트를 시작하고 다시 눌러 중지 해야하는이 예제를 찾았습니다.

이 줄에서 : EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt 인터럽트 모드 또는 이벤트 모드를 선택해야합니다. 이벤트 모드로 변경했지만 작동하지 않는 것 같습니다. 따라서 처리기가 인터럽트 중에 만 실행된다는 결론을 내 렸습니다.

그런 다음 코드가 실행될 때 stm32에서 이벤트를 사용하는 이유는 무엇입니까?

코드는 다음과 같습니다.

        #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)
            {
            }
        }

답변:


14

정보가 종종 데이터 시트에 포함되지 않고 제품군 및 프로그래밍 가이드에 분산되어 있기 때문에 ARM 디바이스에 대한 이러한 질문에 대한 답을 찾는 것이 간단한 마이크로 컨트롤러보다 어려울 수 있습니다. 이 경우에 대한 답변은 RM0090 참조 매뉴얼 381 페이지에있는 것으로 보입니다 .

STM32F4xx는 코어 (WFE)를 깨우기 위해 외부 또는 내부 이벤트를 처리 할 수 ​​있습니다. 웨이크 업 이벤트는 다음 중 하나에 의해 생성 될 수 있습니다.

  • (정상적인 외부 인터럽트 모드 세부 정보를 제거했습니다)

  • 또는 이벤트 모드에서 외부 또는 내부 EXTI 라인을 구성합니다. CPU가 WFE에서 다시 시작되면 이벤트 라인에 해당하는 보류 비트가 설정되지 않았기 때문에 주변 장치 인터럽트 보류 비트 또는 NVIC IRQ 채널 보류 비트를 지울 필요가 없습니다.

따라서 주요 목적은 인터럽트를 생성하지 않거나 정상 작동 중에 인터럽트에 응답하지 않고 웨이크 업을 활성화하는 것입니다.

이 안내서에는 언급되어 있지 않으며 STM32 아키텍처에 적용 가능한 방법이 확실하지 않지만 일부 다른 장치에서는 유사한 체계가 인터럽트를 생성하지 않고 빠른 이벤트를 포착하는 데 유용 할 수 있습니다. 예를 들어 1 마이크로 초 미만의 이벤트가 발생했음을 캡처하는 것이 중요한 응용 프로그램이있을 수 있지만, 신속하게 응답 할 필요가 없으므로 플래그를 확인하여 이벤트가 발생했는지 확인할 수 있습니다.

편집 : (2018 년 5 월) 현재 기준 텍스트의 페이지 번호는 381 페이지입니다 (이전 377 페이지).


1
그래, PIC에서 인터럽트에서 내가하는 일의 대부분은 플래그를 설정 한 것으로 보입니다. Cortex에서 이러한 플래그의 대부분은 중단없이 설정되므로 인터럽트를 적게 사용합니다.
Scott Seidman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.