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アーキテクチャにどのように適用できるかはわかりませんが、他のデバイスでは、同様のスキームが割り込みを生成せずに高速イベントをキャッチするのに役立ちます。たとえば、サブマイクロ秒のイベントが発生したことをキャプチャすることが重要なアプリケーションがありますが、すぐに応答する必要がないため、フラグをチェックして発生したかどうかを確認できます。

編集:(2018年5月)本日現在、参照テキストのページ番号は381ページ(以前のページ377)です。


1
ええ、PICでは、割り込みで行うことの多くはフラグを設定するようです。私はあまり割り込みを使用して皮質では、それらのフラグのほとんどは、中断することなくセットされます
スコット・サイドマン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.