5.11 EXTI 使用说明

本章说明 N32H49x 标准外设库中 EXTI 驱动的文件组成、9 个公开函数,以及 KeyInterrupt 一个示例。中断线与事件线的硬件细节、GPIO 线与 EXTI 线的映射关系请配合用户手册的“EXTI”章节阅读。

5.11.1 相关文件

相对路径 作用
firmware/n32h49x_std_periph_driver/inc/n32h49x_exti.h 定义 EXTI 模式、触发边沿枚举与 EXTI_InitType 结构体,以及 EXTI 线与时间戳线选择宏,并按初始化、软件触发、状态标志、中断、时间戳五个区段声明 9 个公开函数
firmware/n32h49x_std_periph_driver/src/n32h49x_exti.c 实现上述 9 个函数:寄存器复位,屏蔽与触发边沿写入,软件中断触发,状态标志与中断挂起位读写,时间戳输入选择
projects/n32h49x_EVAL/examples/EXTI/ EXTI 示例根目录,含 KeyInterrupt 1 个示例
projects/n32h49x_EVAL/examples/EXTI/KeyInterrupt/ 该示例的工程目录组成:MDK-ARM/、EWARM/、inc/、src/、readme.txt
projects/n32h49x_EVAL/bsp/ 该示例使用的板级支持文件:日志初始化与打印串口重映射

5.11.2 API 参考

搜索 API共 9 个函数

以下 9 个公开函数按 n32h49x_exti.h 的声明顺序分为 5 组;每个条目给出功能摘要与 n32h49x_exti.c 中该函数正上方的注释原文。

初始化

EXTI_DeInit、EXTI_InitPeripheral、EXTI_InitStruct

软件触发

EXTI_TriggerSWInt

状态标志

EXTI_GetStatusFlag、EXTI_ClrStatusFlag

中断

EXTI_GetITStatus、EXTI_ClrITPendBit

时间戳

EXTI_RTCTimeStampSel

void EXTI_DeInit(void)将 EXTI 寄存器复位。
源码注释
name    EXTI_DeInit.
fun     Reset the EXTI registers.
return  none
void EXTI_InitPeripheral(EXTI_InitType* EXTI_InitStruct)按 EXTI_InitStruct 结构体的值初始化 EXTI。
源码注释
name    EXTI_InitPeripheral.
fun     Initializes the EXTI according to EXTI_InitStruct.
param   EXTI_InitStruct(The input parameters must be the following values) :
          - EXTI_Line
            - EXTI_LINE0
            - EXTI_LINE1
            - EXTI_LINE2
            - EXTI_LINE3
            - EXTI_LINE4
            - EXTI_LINE5
            - EXTI_LINE6
            - EXTI_LINE7
            - EXTI_LINE8
            - EXTI_LINE9
            - EXTI_LINE10
            - EXTI_LINE11
            - EXTI_LINE12
            - EXTI_LINE13
            - EXTI_LINE14
            - EXTI_LINE15
            - EXTI_LINE16
            - EXTI_LINE17
            - EXTI_LINE18
            - EXTI_LINE19
            - EXTI_LINE20
            - EXTI_LINE21
            - EXTI_LINE22
            - EXTI_LINE23
            - EXTI_LINE24
          - EXTI_Mode
            - EXTI_Mode_Event
            - EXTI_Mode_Interrupt
          - EXTI_Trigger
            - EXTI_Trigger_Falling
            - EXTI_Trigger_Rising
            - EXTI_Trigger_Rising_Falling
          - EXTI_LineCmd:
            - ENABLE
            - DISABLE
return  none
void EXTI_InitStruct(EXTI_InitType* EXTI_InitStruct)将 EXTI_InitStruct 各成员填充为默认值。
源码注释
name    EXTI_InitStruct.
fun     Fills each EXTI_InitStruct member with its default value.
param   InitStruct :
            - Pointer to the EXTI_InitType structure which will be initialized.
return  none
void EXTI_TriggerSWInt(uint32_t EXTI_Line)产生一次软件中断。
源码注释
name    EXTI_TriggerSWInt.
fun     Generates a Software interrupt.
param   EXTI_Line(The input parameters must be the following values) :
            - EXTI_LINE0
            - EXTI_LINE1
            - EXTI_LINE2
            - EXTI_LINE3
            - EXTI_LINE4
            - EXTI_LINE5
            - EXTI_LINE6
            - EXTI_LINE7
            - EXTI_LINE8
            - EXTI_LINE9
            - EXTI_LINE10
            - EXTI_LINE11
            - EXTI_LINE12
            - EXTI_LINE13
            - EXTI_LINE14
            - EXTI_LINE15
            - EXTI_LINE16
            - EXTI_LINE17
            - EXTI_LINE18
            - EXTI_LINE19
            - EXTI_LINE20
            - EXTI_LINE21
            - EXTI_LINE22
            - EXTI_LINE23
            - EXTI_LINE24
return  none
FlagStatus EXTI_GetStatusFlag(uint32_t EXTI_Line)获取 EXTI 线标志位状态。
源码注释
name    EXTI_GetStatusFlag.
fun     Get EXTI line flag status.
param   EXTI_Line(The input parameters must be the following values) :
            - EXTI_LINE0
            - EXTI_LINE1
            - EXTI_LINE2
            - EXTI_LINE3
            - EXTI_LINE4
            - EXTI_LINE5
            - EXTI_LINE6
            - EXTI_LINE7
            - EXTI_LINE8
            - EXTI_LINE9
            - EXTI_LINE10
            - EXTI_LINE11
            - EXTI_LINE12
            - EXTI_LINE13
            - EXTI_LINE14
            - EXTI_LINE15
            - EXTI_LINE16
            - EXTI_LINE17
            - EXTI_LINE18
            - EXTI_LINE19
            - EXTI_LINE20
            - EXTI_LINE21
            - EXTI_LINE22
            - EXTI_LINE23
            - EXTI_LINE24
return  SET or RESET
void EXTI_ClrStatusFlag(uint32_t EXTI_Line)清除 EXTI 线标志位状态。
源码注释
name    EXTI_ClrStatusFlag.
fun     Clear EXTI line flag status.
param   EXTI_Line :
            - EXTI_LINE0
            - EXTI_LINE1
            - EXTI_LINE2
            - EXTI_LINE3
            - EXTI_LINE4
            - EXTI_LINE5
            - EXTI_LINE6
            - EXTI_LINE7
            - EXTI_LINE8
            - EXTI_LINE9
            - EXTI_LINE10
            - EXTI_LINE11
            - EXTI_LINE12
            - EXTI_LINE13
            - EXTI_LINE14
            - EXTI_LINE15
            - EXTI_LINE16
            - EXTI_LINE17
            - EXTI_LINE18
            - EXTI_LINE19
            - EXTI_LINE20
            - EXTI_LINE21
            - EXTI_LINE22
            - EXTI_LINE23
            - EXTI_LINE24
return  none
INTStatus EXTI_GetITStatus(uint32_t EXTI_Line)获取 EXTI 线中断状态。
源码注释
name    EXTI_GetITStatus.
fun     GET EXTI line interrupt status.
param   exti_line :
            - EXTI_LINE0
            - EXTI_LINE1
            - EXTI_LINE2
            - EXTI_LINE3
            - EXTI_LINE4
            - EXTI_LINE5
            - EXTI_LINE6
            - EXTI_LINE7
            - EXTI_LINE8
            - EXTI_LINE9
            - EXTI_LINE10
            - EXTI_LINE11
            - EXTI_LINE12
            - EXTI_LINE13
            - EXTI_LINE14
            - EXTI_LINE15
            - EXTI_LINE16
            - EXTI_LINE17
            - EXTI_LINE18
            - EXTI_LINE19
            - EXTI_LINE20
            - EXTI_LINE21
            - EXTI_LINE22
            - EXTI_LINE23
            - EXTI_LINE24
return  SET or RESET
void EXTI_ClrITPendBit(uint32_t EXTI_Line)清除 EXTI 线中断挂起位。
源码注释
name    EXTI_ClrITPendBit.
fun     Clear EXTI line interrupt pend bit.
param   exti_line :
            - EXTI_LINE0
            - EXTI_LINE1
            - EXTI_LINE2
            - EXTI_LINE3
            - EXTI_LINE4
            - EXTI_LINE5
            - EXTI_LINE6
            - EXTI_LINE7
            - EXTI_LINE8
            - EXTI_LINE9
            - EXTI_LINE10
            - EXTI_LINE11
            - EXTI_LINE12
            - EXTI_LINE13
            - EXTI_LINE14
            - EXTI_LINE15
            - EXTI_LINE16
            - EXTI_LINE17
            - EXTI_LINE18
            - EXTI_LINE19
            - EXTI_LINE20
            - EXTI_LINE21
            - EXTI_LINE22
            - EXTI_LINE23
            - EXTI_LINE24
return  none
void EXTI_RTCTimeStampSel(uint32_t EXTI_TSSEL_Line)选择 TimeStamp 事件的输入。
源码注释
name    EXTI_RTCTimeStampSel.
fun     Select the input of TimeStamp event.
param   EXTI_TSSEL_Line :
            - EXTI_TSSEL_LINE0
            - EXTI_TSSEL_LINE1
            - EXTI_TSSEL_LINE2
            - EXTI_TSSEL_LINE3
            - EXTI_TSSEL_LINE4
            - EXTI_TSSEL_LINE5
            - EXTI_TSSEL_LINE6
            - EXTI_TSSEL_LINE7
            - EXTI_TSSEL_LINE8
            - EXTI_TSSEL_LINE9
            - EXTI_TSSEL_LINE10
            - EXTI_TSSEL_LINE11
            - EXTI_TSSEL_LINE12
            - EXTI_TSSEL_LINE13
            - EXTI_TSSEL_LINE14
            - EXTI_TSSEL_LINE15
return  none

5.11.3 Demo 示例说明

本节说明 EXTI 的 1 个示例:KeyInterrupt 用一条外部中断线在两条按键引脚之间轮换输入源,并用 LED 与串口提示当前输入源。

5.11.3.1 KeyInterrupt 按键外部中断

工程目录: projects/n32h49x_EVAL/examples/EXTI/KeyInterrupt/

初始化打印串口、两路 LED 与两路按键→把外部中断 0 配置为下降沿触发并使能其中断向量→按键在 PC13 或 PA15 上出现下降沿时进入中断→中断中熄灭当前 LED 并把中断输入源切换到另一路按键→主循环按当前输入源闪烁对应 LED→串口打印当前输入源,交替循环

项目 源码解读
功能 以 EXTI0 为例演示 GPIO 外部中断:默认由 KEY1(PC13)的下降沿触发 EXTI0 中断;
每次进入中断把 EXTI0 输入源在 KEY1 与 KEY2 之间切换一次,串口同步打印当前输入源,闪烁的 LED 随输入源变化。
源码组成 src/main.c:main、LED 与按键的 LED_Init、KEY_Init 以及 EXTI0_Init;
src/n32h49x_it.c:EXTI0_IRQHandler 中断服务函数;
inc/main.h:LED 与按键的端口、引脚、时钟宏与函数声明;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程。
关键配置 LED1 为 PA3、LED2 为 PB3,推挽输出;
KEY1 为 PC13、KEY2 为 PA15,输入上拉。
EXTI0 配置为 EXTI_Mode_Interrupt、EXTI_Trigger_Falling;
EXTI0 输入源由 GPIO_ConfigEXTILine 在 PC13 与 PA15 之间切换。
系统时钟为 HSI+PLL,240 MHz。
程序与数据路径 main 调用 log_init 并打印 EXTI key interrupt demo!,初始化两路 LED 与两路按键后调用 EXTI0_Init,把 EXTI0 输入源接到 KEY1;
主循环中当 exti_int 置位时打印 Current EXTI0 input source is:%s,并按 key_cnt 闪烁对应 LED,间隔为 SystemCoreClock/8。
主要 API EXTI_InitStruct、EXTI_InitPeripheral、GPIO_ConfigEXTILine、EXTI_GetStatusFlag、EXTI_ClrStatusFlag
验证方法 复位运行后串口打印 EXTI key interrupt demo!;
默认按下 KEY1 触发 EXTI0 中断,此后输入源切换到 KEY2,只有 KEY2 能再次触发;
每次触发后闪烁的 LED 在 LED1 与 LED2 之间切换,串口提示当前输入源。
使用提示 中断服务函数中先读 EXTI_GetStatusFlag 判断状态,再用 EXTI_ClrStatusFlag 清除挂起位;
切换输入源后原引脚不再触发中断,需再次调用 GPIO_ConfigEXTILine 才会改用新引脚。
开发环境为 KEIL MDK-ARM V5.34 或 IAR EWARM 8.50.1。
核心代码解读与移植

示例用一个中断服务函数在两条按键引脚之间轮换 EXTI0 的输入源,并让 LED 跟随当前输入源闪烁。

数据路径: KEY1(PC13)或 KEY2(PA15)的下降沿 → GPIO_ConfigEXTILine 选定 EXTI0 输入源 → EXTI_InitPeripheral 使能 EXTI0 下降沿中断 → 进入 EXTI0_IRQHandler → EXTI_GetStatusFlag 判状态、EXTI_ClrStatusFlag 清标志 → 把输入源切换到下一路按键 → 主循环按 key_cnt 闪烁对应 LED 并打印输入源

1. 用宏与数组集中定义 LED 与按键。 引脚与端口都在 inc/main.h 中定义,示例通过 LEDx_PORT、LEDx_PIN、KEYx_PORT、KEYx_PIN 访问,按键的端口源与引脚源另用数组登记,便于在中断里切换。

inc/main.hinc/main.h
/* User LED define */
#define LED1_PORT   GPIOA
#define LED1_PIN    GPIO_PIN_3
#define LED1_CLOCK  RCC_AHB_PERIPHEN_GPIOA


#define LED2_PORT   GPIOB
#define LED2_PIN    GPIO_PIN_3
#define LED2_CLOCK  RCC_AHB_PERIPHEN_GPIOB


/* User KEY define */
#define KEY1_PORT   GPIOC
#define KEY1_PIN    GPIO_PIN_13
#define KEY1_CLOCK  RCC_AHB_PERIPHEN_GPIOC

#define KEY2_PORT   GPIOA
#define KEY2_PIN    GPIO_PIN_15
#define KEY2_CLOCK  RCC_AHB_PERIPHEN_GPIOA

更换板卡或按键引脚时,只需修改这组宏以及 src/main.c 中的 KeyPortSrc、KeyPinSrc 数组,示例逻辑不用改动。

2. 把 EXTI0 配为下降沿中断并绑定输入源。 EXTI0_Init 填写 EXTI_InitType 后使能 EXTI0 下降沿中断,同时配置 NVIC 的 EXTI0 中断通道,最后把 GPIO 引脚映射到 EXTI0。

src/main.csrc/main.c · EXTI0_Init
    EXTI_Struct.EXTI_Line    = EXTI_LINE0;
    EXTI_Struct.EXTI_Mode    = EXTI_Mode_Interrupt;
    EXTI_Struct.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_Struct.EXTI_LineCmd = ENABLE;
    EXTI_InitPeripheral(&EXTI_Struct);

    NVIC_Struct.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_Struct.NVIC_IRQChannelSubPriority = NVIC_SUB_PRIORITY_0;
    NVIC_Struct.NVIC_IRQChannelPreemptionPriority = NVIC_PRE_PRIORITY_0;
    NVIC_Struct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_Struct);

    GPIO_ConfigEXTILine(EXTI_LINE_SOURCE0,KeyPortSrc[0],KeyPinSrc[0]);

EXTI_Trigger_Falling 决定只在下降沿触发;GPIO_ConfigEXTILine 把选定的端口源与引脚源接到 EXTI0,实现与用户手册中 EXTI 线选择寄存器的 GPIO 映射一致。

3. 中断服务函数切换输入源。 EXTI0_IRQHandler 判断 EXTI0 状态后熄灭当前 LED,把 key_cnt 在 0 与 1 之间循环,再重新映射输入源,最后清除挂起位。

src/n32h49x_it.csrc/n32h49x_it.c · EXTI0_IRQHandler
    if(EXTI_GetStatusFlag(EXTI_LINE0) == SET)
    {
        LED_Off(LedPort[key_cnt], LedPin[key_cnt]);
        
        if(key_cnt >= (MAX_LED_KEY_CNT-1))
        {
            key_cnt = 0;
        }
        else
        {
            key_cnt++;
        }

        GPIO_ConfigEXTILine(EXTI_LINE_SOURCE0,KeyPortSrc[key_cnt],KeyPinSrc[key_cnt]);
        exti_int = 1;
    }
    
    EXTI_ClrStatusFlag(EXTI_LINE0);

每次中断先由 EXTI_GetStatusFlag 确认来源,再由 GPIO_ConfigEXTILine 把 EXTI0 改接到下一路按键;末尾 EXTI_ClrStatusFlag 清除挂起位,避免中断反复进入。

4. 主循环按输入源打印并闪烁。 main 检测 exti_int,置位时打印当前输入源并把标志清零,随后始终按 key_cnt 闪烁对应 LED。

src/main.csrc/main.c · main
    while (1)
    {
        if(exti_int != 0)
        {
            printf("Current EXTI0 input source is:%s\r\n",str[key_cnt]);
            exti_int = 0;
        }

        LED_Blink(LedPort[key_cnt], LedPin[key_cnt]);
        Delay(SystemCoreClock/8);
    }

闪烁节奏由 Delay(SystemCoreClock/8) 决定;str[] 数组提供串口提示用的引脚名称,与 KeyPortSrc、KeyPinSrc 一一对应。

对应源码: src/main.c、inc/main.h、src/n32h49x_it.c

5.11.4 注意与排障

场景 检查与建议 来源
中断使能 使用 EXTI 中断前须使能 NVIC 中对应的中断通道,并正确设置 EXTI 中断屏蔽寄存器中对应线的屏蔽位;
两者缺一,边沿到来时不会进入中断服务程序。
用户手册
挂起位清除 检测到边沿后对应线的挂起位置 1,须在中断服务程序中向该位写 1 清除;
改变该线的边沿极性也会清除挂起位。
用户手册
事件与中断的区别 事件线通过事件屏蔽寄存器配置,事件产生时只输出脉冲,不会置位挂起位;
只配置事件而不配置中断时,CPU 不会进入中断服务程序。
用户手册
特定外设的边沿限制 使用 PVD、USB FS、USB HS、LPTIM1、LPTIM2 中断时,其关联的 EXTI 线只能配置为上升沿触发。 用户手册
GPIO 线映射与 AFIO 时钟 通过 AFIO_EXTI_CFGy 把 GPIO 引脚映射到 EXTI 线之前,必须先使能 AFIO 时钟;
同一条 EXTI 线同一时刻只能映射到一个 GPIO 引脚。
用户手册
国民技术开发套件文档中心

按芯片系列在线查阅国民技术 MCU 开发套件的芯片资料、SDK、驱动 API 与 Demo 示例说明。

© 2026 国民技术股份有限公司 版权所有粤ICP备11069485号本站使用不含 Cookie 的匿名访问统计