Stm32 Evento e interruzioni


17

Ho iniziato a studiare gli interrupt su stm32 in particolare la scheda di rilevamento stm32f4. ho trovato questo esempio in cui devi premere il pulsante per avviare l'interrupt e spingerlo di nuovo per interromperlo.

In questa riga: EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt dobbiamo scegliere la modalità di interruzione o la modalità evento. L'ho cambiato in modalità evento ma non sembra funzionare. Quindi sono uscito con la conclusione che il gestore viene eseguito solo con interruzioni.

Perché utilizziamo quindi Eventi su stm32 se non riesci a eseguire del codice quando si verificano?

Ecco il codice:

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

Risposte:


14

A volte trovare la risposta a queste domande per un dispositivo ARM può essere più difficile dei microcontrollori più semplici perché le informazioni sono spesso diffuse tra la famiglia e le guide di programmazione piuttosto che incluse nel foglio dati. In questo caso la risposta sembra essere a pagina 381 del manuale di riferimento di RM0090 :

Gli STM32F4xx sono in grado di gestire eventi esterni o interni per riattivare il core (WFE). L'evento wakeup può essere generato da:

  • (Ho rimosso i dettagli della normale modalità di interruzione esterna)

  • o la configurazione di una linea EXTI esterna o interna in modalità evento. Quando la CPU riprende da WFE, non è necessario cancellare il bit in sospeso di interruzione periferica o il bit in sospeso del canale IRQ NVIC poiché il bit in sospeso corrispondente alla linea di eventi non è impostato.

Quindi sembra che lo scopo principale sia abilitare i wakeup senza generare un interrupt o dover rispondere agli interrupt durante il normale funzionamento.

Non è menzionato in quella guida e non sono sicuro di quanto sia applicabile all'architettura STM32 ma su alcuni altri dispositivi schemi simili possono essere utili per catturare eventi veloci senza generare un interrupt. Ad esempio, potresti avere un'applicazione in cui è importante rilevare che si è verificato un evento sub-microsecondo, ma non è necessario rispondere rapidamente in modo da poter semplicemente controllare un flag per vedere se si è verificato.

Modifica: (5/2018) Ad oggi, il numero di pagina del testo di riferimento è pagina 381 (precedentemente pagina 377)


1
Sì, su PIC sembra che gran parte di ciò che faccio in un interrupt sia impostato flag. In Cortex, la maggior parte di quelle bandiere viene impostata senza dover interrompere, quindi utilizzo meno interruzioni
Scott Seidman,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.