Input Interrupt

该示例使用 GPIO 中断功能,检测GPIO的输入信号。 首先将GPIO配置为输入并打开中断功能。当输入信号变化触发中断,中断服务处理函数会打印输入电平信息。

环境需求

该示例支持以下开发套件:

开发套件

Hardware Platforms

Board Name

RTL87x2G HDK

RTL87x2G EVB

更多信息请参考 快速入门

硬件连线

连接P4_0和外部输入信号。

编译和下载

该示例的工程路径如下:

Project file: samples\peripheral\gpio\input_interrupt\proj\rtl87x2g\mdk

Project file: samples\peripheral\gpio\input_interrupt\proj\rtl87x2g\gcc

请按照以下步骤操作构建并运行该示例:

  1. 打开工程文件。

  2. 按照 Quick Start编译APP Image 给出的步骤构建目标文件。

  3. 编译成功后,在路径 mdk\bingcc\bin 下会生成 app bin app_MP_xxx.bin 文件。

  4. 按照 快速入门MPTool 给出的步骤将app bin烧录至EVB内。

  5. 按下复位按键,开始运行。

测试验证

  1. 当EVB启动后,在DebugAnalyzer工具内观察LOG。

    Start input interrupt test!
    
  2. 控制外部输入信号从高电平变为低电平,P4_0检测到下降沿信号触发中断,中断处理函数 GPIO_Input_Handler 中显示如下LOG。

    enter GPIO_Pin_Handler success
    

代码介绍

该章节分为以下几个部分:

  1. 源码路径.

  2. 初始化函数将在 初始化 章节介绍。

  3. 初始化后的功能实现将在 功能实现 章节介绍。

源码路径

  • 工程路径: sdk\samples\peripheral\gpio\input_interrupt\proj

  • 源码路径: sdk\samples\peripheral\gpio\input_interrupt\src

该工程的工程文件代码结构如下:

└── Project: output_toggle
    └── secure_only_app
        └── Device                   includes startup code
            ├── startup_rtl.c
            └── system_rtl.c
        ├── CMSIS                    includes CMSIS header files
        ├── CMSE Library             Non-secure callable lib
        ├── lib                      includes all binary symbol files that user application is built on
            └── rtl87x2g_io.lib
        ├── peripheral               includes all peripheral drivers and module code used by the application
            ├── rtl_gpio.c
            ├── rtl_pinmux.c
            └── rtl_rcc.c
        └── APP                      includes the ble_peripheral user application implementation
            ├── io_gpio.c
            └── main_ns.c

初始化

初始化流程包括了 board_gpio_initdriver_gpio_init


board_gpio_init 中包含了PAD与PINMUX设置:

  1. 配置PAD:设置引脚、PINMUX模式、PowerOn、无内部上拉。

  2. 配置PINMUX:分配引脚为GPIO功能。


driver_gpio_init 包含了对GPIO外设的初始化:

  1. 使能 PCC 时钟源。

  2. 设置 GPIO_Mode 为输入模式。

  3. 使能GPIO中断。

  4. 设置GPIO中断触发模式 GPIO_ITTrigger 为边沿触发。

  5. 设置GPIO中断极性 GPIO_ITPolarity 为下降沿触发。

  6. 开启GPIO Debounce功能。

    1. 设置GPIO Debounce功能的时钟频率,时钟分频和去抖动计数值。

  7. 初始化中断:设置中断优先级,并使能GPIO_PIN_INPUT_IRQN通道。

  8. 屏蔽GPIO外部中断,使能GPIO中断,清除GPIO中断标志位,取消屏蔽GPIO外部中断。

RCC_PeriphClockCmd(APBPeriph_GPIOB, APBPeriph_GPIOB_CLOCK, ENABLE);
...
GPIO_InitStruct.GPIO_Mode       = GPIO_DIR_IN;
GPIO_InitStruct.GPIO_ITCmd      = ENABLE;
GPIO_InitStruct.GPIO_ITTrigger  = GPIO_INT_Trigger_EDGE;
GPIO_InitStruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW;

GPIO_InitStruct.GPIO_ITDebounce        = GPIO_INT_DEBOUNCE_ENABLE;
GPIO_InitStruct.GPIO_DebounceClkSource = GPIO_DEBOUNCE_32K;
GPIO_InitStruct.GPIO_DebounceClkDiv    = GPIO_DEBOUNCE_DIVIDER_1;
GPIO_InitStruct.GPIO_DebounceCntLimit  = 32 - 1;
...
NVIC_Init(&NVIC_InitStruct);

GPIO_MaskINTConfig(GPIO_PORT, GPIO_PIN, ENABLE);
GPIO_INTConfig(GPIO_PORT, GPIO_PIN, ENABLE);
GPIO_ClearINTPendingBit(GPIO_PORT, GPIO_PIN);
GPIO_MaskINTConfig(GPIO_PORT, GPIO_PIN, DISABLE);

小技巧

对于GPIO中断异常的处理,详见 常见问题

功能实现

当P4_0检测到外部有下降沿信号输入时,进入中断服务处理函数 GPIO_Pin_Handler 。打印中断信息。 在中断处理函数中需要先关闭并屏蔽中断,退出中断函数时清除中断标志位、取消屏蔽和重新使能中断。

/* Mask and disable interrupt */
GPIO_INTConfig(GPIO_PORT, GPIO_PIN, DISABLE);
GPIO_MaskINTConfig(GPIO_PORT, GPIO_PIN, ENABLE);

DBG_DIRECT("enter GPIO_Pin_Handler success");

/* Clear int flag, unmask and enable interrupt */
GPIO_ClearINTPendingBit(GPIO_PORT, GPIO_PIN);
GPIO_MaskINTConfig(GPIO_PORT, GPIO_PIN, DISABLE);
GPIO_INTConfig(GPIO_PORT, GPIO_PIN, ENABLE);

常见问题

GPIO误触发中断

GPIO在如下四种模式下会误触发一次中断:

  • PAD 设置为 输入高,采用 上升沿 触发中断。

  • PAD 设置为 输入高,采用 双边沿 触发中断。

  • PAD 设置为 输入低,采用 下降沿 触发中断。

  • PAD 设置为 输入低,采用 双边沿 触发中断。

为避免中断误触发,在GPIO中断配置时应遵循如下设置流程:

  1. 屏蔽GPIO中断:GPIO_MaskINTConfig(GPIO_PORT, GPIO_PIN, ENABLE)

  2. 使能GPIO中断:GPIO_INTConfig(GPIO_PORT, GPIO_PIN,ENABLE)

  3. 清除GPIO中断标志位:GPIO_ClearPendingBit(GPIO_PORT, GPIO_PIN)

  4. 取消屏蔽GPIO中断:GPIO_MastINTConfig(GPIO_PORT, GPIO_PIN,DISABLE)

若需要更改GPIO中断配置时,应遵循如下设置流程:

  1. 屏蔽GPIO中断:GPIO_MaskINTConfig(GPIO_PORT, GPIO_PIN,ENABLE)

  2. 修改GPIO中断配置(设置中断触发类型和极性):GPIO_SetITTrigger(GPIO_PORT ,GPIO_PIN, GPIO_TriggerMode) GPIO_SetITPolarity(GPIO_PORT, GPIO_PIN, GPIO_ITPolarity)...

  3. 清除GPIO中断标志位:GPIO_ClearPendingBit(GPIO_PORT, GPIO_PIN)

  4. 取消屏蔽GPIO中断:GPIO_MastINTConfig(GPIO_PORT, GPIO_PIN, DISABLE)