查看: 3662|回复: 1

RT1052+6、MDK环境 GPIO输入中断分析

[复制链接]
  • TA的每日心情
    开心
    2024-4-10 10:22
  • 签到天数: 1317 天

    [LV.10]以坛为家III

    124

    主题

    2831

    帖子

    31

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    7570
    最后登录
    2024-4-10
    发表于 2018-10-26 23:11:36 | 显示全部楼层 |阅读模式
        通过GPIO终端输入例程来学习了中断配置。    例程例程:按键K3触发中断,进入中断后,通过串口打印出按键信息。
        一、硬件电路:
             101.png
             102.png
            K3按键进入RT1052的L6引脚,对应的端口是GPIO5_IO00。
             103.png
        二、程序:
            2.1、主程序:
            int main(void)
            {
                gpio_pin_config_t sw_config = {
                kGPIO_DigitalInput, 0,     //端口设置为输入
                kGPIO_IntRisingEdge,      //端口设置为上升沿中断           
                };

            BOARD_ConfigMPU();
            BOARD_InitPins();        //初始化引脚
            BOARD_BootClockRUN();
            BOARD_InitDebugConsole();
            PRINTF("GPIO Driver example.\r\n");


            EnableIRQ(EXAMPLE_SW_IRQ);     //使能中断
            GPIO_PinInit(EXAMPLE_SW_GPIO, EXAMPLE_SW_GPIO_PIN, &sw_config);   //初始化GPIO5_IO00引脚
            GPIO_PortEnableInterrupts(EXAMPLE_SW_GPIO, 1U << EXAMPLE_SW_GPIO_PIN);

            while(1)
           {
                if(g_InputSignal)
                {
                    delay();
                    if(1 == GPIO_PinRead(EXAMPLE_SW_GPIO, EXAMPLE_SW_GPIO_PIN))
                    {
                        PRINTF("%s is turned on.\r\n", EXAMPLE_SW_NAME);
                    }
                    g_InputSignal = false;
                }
            }
        }
            //中断程序
            void EXAMPLE_GPIO_IRQHandler(void)
            {
                 GPIO_PortClearInterruptFlags(EXAMPLE_SW_GPIO, 1U << EXAMPLE_SW_GPIO_PIN);
                 g_InputSignal = true;
                 exception return operation might vector to incorrect interrupt */
                 #if defined __CORTEX_M && (__CORTEX_M == 4U)
                     __DSB();
                 #endif
             }
        2.2、对上面红色字体的函数进行分析
            2.2.1、 BOARD_InitPins();        //初始化引脚
    这个函数在 pin_mux.c中定义
           void BOARD_InitPins(void)
            {
                CLOCK_EnableClock(kCLOCK_Iomuxc);           
                CLOCK_EnableClock(kCLOCK_IomuxcSnvs);   

            IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U);        //复用GPIO引脚设置为串口1   
                IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX,  0U);               
                IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0U);           //GPIO5_IO00配置为输入
                IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0u);                              
                IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0u);                             
            }
            2.2.2、 EnableIRQ(EXAMPLE_SW_IRQ);     //使能中断
                   这个函数在fsl_common.h中定义
                static inline status_t EnableIRQ(IRQn_Type interrupt)
                {
                    if (NotAvail_IRQn == interrupt)
                    {
                        return kStatus_Fail;
    }
                        NVIC_EnableIRQ(interrupt);
                     return kStatus_Success;
                }

                IRQn_Type结构中有关GPIO口的定义:
                typedef enum IRQn {
                  /* Auxiliary constants */
                  NotAvail_IRQn                = -128,             /**< Not available device specific interrupt */


                  GPIO1_INT0_IRQn              = 72,               /**< Active HIGH Interrupt from INT0 from GPIO */
                  GPIO1_INT1_IRQn              = 73,               /**< Active HIGH Interrupt from INT1 from GPIO */
                  GPIO1_INT2_IRQn              = 74,               /**< Active HIGH Interrupt from INT2 from GPIO */
                  GPIO1_INT3_IRQn              = 75,               /**< Active HIGH Interrupt from INT3 from GPIO */
                  GPIO1_INT4_IRQn              = 76,               /**< Active HIGH Interrupt from INT4 from GPIO */
                  GPIO1_INT5_IRQn              = 77,               /**< Active HIGH Interrupt from INT5 from GPIO */
                  GPIO1_INT6_IRQn              = 78,               /**< Active HIGH Interrupt from INT6 from GPIO */
                  GPIO1_INT7_IRQn              = 79,               /**< Active HIGH Interrupt from INT7 from GPIO */
                  GPIO1_Combined_0_15_IRQn     = 80,               /**< Combined interrupt indication for GPIO1 signal 0 throughout 15 */
                  GPIO1_Combined_16_31_IRQn    = 81,               /**< Combined interrupt indication for GPIO1 signal 16 throughout 31 */
                  GPIO2_Combined_0_15_IRQn     = 82,               /**< Combined interrupt indication for GPIO2 signal 0 throughout 15 */
                  GPIO2_Combined_16_31_IRQn    = 83,               /**< Combined interrupt indication for GPIO2 signal 16 throughout 31 */
                  GPIO3_Combined_0_15_IRQn     = 84,               /**< Combined interrupt indication for GPIO3 signal 0 throughout 15 */
                  GPIO3_Combined_16_31_IRQn    = 85,               /**< Combined interrupt indication for GPIO3 signal 16 throughout 31 */
                  GPIO4_Combined_0_15_IRQn     = 86,               /**< Combined interrupt indication for GPIO4 signal 0 throughout 15 */
                  GPIO4_Combined_16_31_IRQn    = 87,               /**< Combined interrupt indication for GPIO4 signal 16 throughout 31 */
                  GPIO5_Combined_0_15_IRQn     = 88,               /**< Combined interrupt indication for GPIO5 signal 0 throughout 15 */
                  GPIO5_Combined_16_31_IRQn    = 89,               /**< Combined interrupt indication for GPIO5 signal 16 throughout 31 */

               } IRQn_Type;
            >中断使能参数定义:
    #define EXAMPLE_SW_IRQ BOARD_USER_BUTTON_IRQ
              #define BOARD_USER_BUTTON_IRQ GPIO5_Combined_0_15_IRQn
              调用EnableIRQ(EXAMPLE_SW_IRQ);     函数的参数就是上面定义的中断号为88


                NVIC_EnableIRQ(interrupt);函数定义:
                #define NVIC_EnableIRQ              __NVIC_EnableIRQ
    __NVIC_EnableIRQ函数定义:

    /**
                  \brief   Enable Interrupt
                  \details Enables a device specific interrupt in the NVIC interrupt controller.
                  \param [in]      IRQn  Device specific interrupt number.
                  \note    IRQn must not be negative.
               */
      __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
               {
                      if ((int32_t)(IRQn) >= 0)
                     {
                          NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
                     }
               }
              NVIC内存映射地址:
              #define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
    #define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
                #define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
              NVIC结构体的定义:
              /**
                   \ingroup    CMSIS_core_register
                   \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
                   \brief      Type definitions for the NVIC Registers
                   @{
              */

              typedef struct
              {
                    __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
                              uint32_t RESERVED0[24U];
                    __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
                              uint32_t RSERVED1[24U];
                    __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
                              uint32_t RESERVED2[24U];
                    __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
                              uint32_t RESERVED3[24U];
                    __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
                              uint32_t RESERVED4[56U];
                    __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
                              uint32_t RESERVED5[644U];
                    __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
                }  NVIC_Type;


               ISER映射的地址就是:0xE000E100UL   
    这个地址在RT1052手册中没有找到,从上面的定义说明可以看出来,这是CMSIS_core_register 内核寄存器。
              没有找到M7内核资料,从Cortex-M3权威指南中找到相关寄存器:
                 301.png
                 302.png
                 303.png

                
            2.2.3、GPIO_PortEnableInterrupts(EXAMPLE_SW_GPIO, 1U << EXAMPLE_SW_GPIO_PIN);
                这个函数在fsl_gpio.c中定义
                void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *Config)
                {
                    #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
                     /* Enable GPIO clock. */
                    CLOCK_EnableClock(s_gpioClock[GPIO_GetInstance(base)]);
                    #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

                     /* Register reset to default value */
                     base->IMR &= ~(1U << pin);        

                     /* Configure GPIO pin direction */
                     if (Config->direction == kGPIO_DigitalInput)     //GPIO设置为输入
                     {
                          base->GDIR &= ~(1U << pin);
                     }
                     else
                     {
                           GPIO_PinWrite(base, pin, Config->outputLogic);
                           base->GDIR |= (1U << pin);
                      }

                      /* Configure GPIO pin interrupt mode */
                      GPIO_SetPinInterruptConfig(base, pin, Config->interruptMode);  //配置中断模式,程序开始就设置为上升沿中断模式
                 }
                RT1052手册中有关GPIO中断配置相关的寄存器
                 201.png
                 202.png
                 203.png
        三、实验结果:
            通过对上面寄存器的分析,对GPIO中断配置有了新的认识。
             401.png







    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情

    2021-2-4 09:24
  • 签到天数: 190 天

    [LV.7]常住居民III

    38

    主题

    591

    帖子

    28

    金牌会员

    Rank: 6Rank: 6

    积分
    2193
    最后登录
    2023-12-1
    发表于 2018-10-27 08:59:51 | 显示全部楼层
    写得很详细 学习了
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-25 22:07 , Processed in 0.116222 second(s), 23 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表