Stm32 Olayı ve Kesmeler


17

Stm32'de özellikle stm32f4 keşif panosunda kesintiler çalışmaya başladım. Kesmeyi başlatmak için düğmeye basmanız ve durdurmak için tekrar itmeniz gereken bu örneği buldum.

Bu satırda: EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt kesme modunu veya olay modunu seçmeliyiz. Ben olay moduna değiştirdim ama işe yaramıyor gibi görünüyor.Bu yüzden işleyicinin sadece kesintilerle yürütüldüğü sonucuna vardım.

O zaman neden bazı kodları yürütemezseniz stm32'de Events'i kullanıyoruz?

İşte kod:

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

Yanıtlar:


14

Bazen bir ARM cihazı için bu soruların cevabını bulmak daha basit mikrodenetleyicilerden daha zor olabilir, çünkü bilgi veri sayfasına dahil olmak yerine genellikle aile ve programlama kılavuzlarına yayılır. Bu durumda cevap RM0090 Referans kılavuzunun 381. sayfasında görünmektedir :

STM32F4xx, çekirdeği (WFE) uyandırmak için harici veya dahili olayları işleyebilir. Uyandırma olayı aşağıdakiler tarafından oluşturulabilir:

  • (Normal harici kesme modu ayrıntılarını kaldırdım)

  • veya olay modunda harici veya dahili bir EXTI hattını yapılandırma. CPU WFE'den devam ettiğinde, olay satırına karşılık gelen bekleyen bit ayarlanmadığından, çevresel kesme bekleyen bitini veya NVIC IRQ kanalı bekleyen bitini temizlemek gerekli değildir.

Bu yüzden asıl amaç, bir kesinti oluşturmadan veya normal çalışma sırasında kesintilere yanıt vermek zorunda kalmadan uyanmaları etkinleştirmektir.

Bu kılavuzda bahsedilmedi ve STM32 mimarisi için ne kadar geçerli olduğundan emin değilim, ancak diğer bazı cihazlarda benzer şemalar, kesintiye neden olmadan hızlı olayları yakalamak için yararlı olabilir. Örneğin, bir mikrosaniye-altı olayın meydana geldiğini yakalamanın önemli olduğu bir uygulamanız olabilir, ancak buna hızlı bir şekilde yanıt vermenize gerek yoktur, böylece bir bayrak olup olmadığını kontrol edebilirsiniz.

Düzenleme: (5/2018) Bugün itibarıyla, atıfta bulunulan metnin sayfa numarası sayfa 381'dir (önceki sayfa 377)


1
Evet, PIC'lerde bir kesintide yaptığımın çoğunun bayraklar olduğu anlaşılıyor. Cortex'te, bu bayrakların çoğu kesintiye gerek kalmadan ayarlanır, bu yüzden daha az kesinti kullanırım
Scott Seidman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.