Sự kiện Stm32 và gián đoạn


17

Tôi bắt đầu nghiên cứu các ngắt trên stm32 cụ thể là bảng khám phá stm32f4. tôi tìm thấy ví dụ này trong đó bạn phải nhấn nút để bắt đầu ngắt và đẩy nó một lần nữa để dừng nó.

Trong dòng này: EXTI_InitStr struct.EXTI_Mode = EXTI_Mode_Interrupt chúng ta phải chọn chế độ ngắt hoặc chế độ sự kiện. Tôi đã thay đổi nó sang chế độ sự kiện nhưng dường như nó không hoạt động. Vì vậy, tôi đã đưa ra kết luận rằng trình xử lý được thực thi chỉ với các ngắt.

Tại sao sau đó chúng tôi sử dụng Sự kiện trên stm32 nếu bạn không thể thực thi một số mã khi chúng xảy ra?

Đây là mã:

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

Câu trả lời:


14

Đôi khi, việc tìm câu trả lời cho những câu hỏi này cho một thiết bị ARM có thể khó hơn các bộ vi điều khiển đơn giản hơn vì thông tin thường được lan truyền trên các hướng dẫn lập trình và gia đình thay vì được đưa vào bảng dữ liệu. Trong trường hợp này, câu trả lời dường như nằm ở trang 381 của tài liệu tham khảo RM0090 :

STM32F4xx có thể xử lý các sự kiện bên ngoài hoặc bên trong để đánh thức lõi (WFE). Sự kiện đánh thức có thể được tạo ra bởi:

  • (Tôi đã xóa chi tiết chế độ ngắt ngoài bình thường)

  • hoặc định cấu hình dòng EXTI bên ngoài hoặc bên trong trong chế độ sự kiện. Khi CPU hoạt động trở lại từ WFE, không cần thiết phải xóa bit đang chờ ngắt ngoại vi hoặc bit chờ của kênh NVIC IRQ vì bit chờ xử lý tương ứng với dòng sự kiện không được đặt.

Vì vậy, nó xuất hiện mục đích chính là để kích hoạt đánh thức mà không tạo ra một ngắt hoặc phải đáp ứng với các ngắt trong hoạt động bình thường.

Nó không được đề cập trong hướng dẫn đó và tôi không chắc cách áp dụng cho kiến ​​trúc STM32 nhưng trên một số thiết bị khác, các lược đồ tương tự có thể hữu ích để bắt các sự kiện nhanh mà không gây gián đoạn. Ví dụ: bạn có thể có một ứng dụng trong đó rất quan trọng để nắm bắt rằng sự kiện dưới micro giây đã xảy ra, nhưng không cần phải phản hồi nhanh vì vậy bạn chỉ cần kiểm tra một lá cờ để xem nó có xảy ra không.

Chỉnh sửa: (5/2018) Tính đến hôm nay, số trang của văn bản được tham chiếu là trang 381 (trước đây là trang 377)


1
Vâng, trên PIC có vẻ như phần lớn những gì tôi làm trong một ngắt được đặt cờ. Trong Cortex, hầu hết các cờ đó được đặt mà không phải ngắt, vì vậy tôi sử dụng ít ngắt hơn
Scott Seidman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.