5.5 EXTI 使用说明
本章说明 N32G033 标准外设库中 EXTI 驱动的文件组成、8 个公开函数,以及 KeyInterrupt 1 个示例。外部中断线的触发沿、事件模式与引脚映射请配合用户手册的“EXTI”章节阅读,引脚复用编号见 AFIO 相关章节,芯片已知问题以勘误手册为准。
5.5.1 相关文件
| 相对路径 | 作用 |
|---|---|
firmware/n32g033_std_periph_driver/inc/n32g033_exti.h |
定义 EXTI_InitType 结构体与触发沿、中断与事件模式等宏,并按一段连续声明 8 个公开函数 |
firmware/n32g033_std_periph_driver/src/n32g033_exti.c |
实现上述 8 个函数:EXTI 复位与初始化、软件中断、状态标志与中断挂起位的读取与清除 |
projects/n32g033_EVAL/examples/EXTI/ |
EXTI 示例根目录,含 KeyInterrupt 1 个示例 |
projects/n32g033_EVAL/examples/EXTI/KeyInterrupt/ |
该示例的工程目录组成:MDK-ARM/、EWARM/、inc/、src/、readme.txt |
projects/n32g033_EVAL/bsp/ |
示例共用的板级支持文件:log.h 提供串口日志接口 |
5.5.2 API 参考
以下 8 个公开函数按 n32g033_exti.h 的声明顺序分为 1 组;每个条目给出功能摘要与 n32g033_exti.c 中该函数正上方的注释原文。
初始化、触发与标志处理
EXTI_DeInit、EXTI_InitPeripheral、EXTI_InitStruct、EXTI_TriggerSWInt、EXTI_GetStatusFlag、EXTI_ClrStatusFlag、EXTI_GetITStatus、EXTI_ClrITPendBit
void EXTI_DeInit(void)复位 EXTI 寄存器。
name EXTI_DeInit.
fun Reset the EXTI registers.
return none
void EXTI_InitPeripheral(const 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_LINENONE
- EXTI_LINE0
- EXTI_LINE1
- EXTI_LINE2
- EXTI_LINE3
- EXTI_LINE4
- EXTI_LINE5
- EXTI_LINE6
- EXTI_LINE7
- EXTI_LINE8
- EXTI_LINE9
- EXTI_LINE10
- EXTI_Mode
- EXTI_Mode_Interrupt
- EXTI_Mode_Event
- EXTI_Trigger
- EXTI_Trigger_Rising
- EXTI_Trigger_Falling
- 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 EXTI_StructInit :
- - 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
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
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
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
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
return none
5.5.3 Demo 示例说明
本节说明 EXTI 的 1 个示例:KeyInterrupt 用按键引脚上的外部中断控制 LED 闪烁。
5.5.3.1 KeyInterrupt 按键外部中断
工程目录: projects/n32g033_EVAL/examples/EXTI/KeyInterrupt/
使能 GPIO 时钟并把按键引脚配成上拉输入→把按键引脚接到对应的 EXTI 线→设置 EXTI 线为下降沿中断并使能→按键动作在引脚上产生下降沿→中断服务翻转 LED
| 项目 | 源码解读 |
|---|---|
| 功能 | 用外部中断控制 LED 闪烁:按下并松开 KEY2 时 PA4 上的电平变化触发中断,中断里翻转 PA7 上的 LED。 |
| 源码组成 | src/main.c 含 main、KeyInputExtiInit,以及 LedInit、LedOn、LedOff、LedBlink 等 LED 操作函数;src/n32g033_it.c 中的 EXTI0_6_IRQHandler 处理中断;inc/main.h、inc/n32g033_it.h 给出声明与引脚宏;readme.txt 给出测试步骤;工程文件在 MDK-ARM/ 与 EWARM/。 |
| 关键配置 | PA4 配成上拉输入并作为外部中断入口,PA7 配成推挽输出驱动 LED; EXTI 线设为下降沿触发、中断模式; 中断通道 EXTI0_6_IRQn,优先级 NVIC_PRIORITY_1。 |
| 程序与数据路径 | main → LedInit 配置 PA6、PA7 → KeyInputExtiInit 配置 PA4 的 GPIO 与 EXTI 并打开中断 → LedOn 点亮 LED1 → 主循环空转 → 按下松开 KEY2 在 PA4 产生下降沿 → EXTI0_6_IRQHandler 翻转 PA7 并清除挂起位。 |
| 主要 API | EXTI_InitPeripheral、GPIO_ConfigEXTILine、EXTI_GetStatusFlag、EXTI_ClrITPendBit、NVIC_Init |
| 验证方法 | 硬件基于评估板 N32G033K8Q7-1_STB V1.0,串口 TX 为 PA9、RX 为 PA10,波特率 115200; 编译下载复位运行后,按下并松开 KEY2,PA7 上的 LED 翻转一次。 |
| 使用提示 | 系统时钟 64 MHz; 引脚宏在 inc/main.h 中统一定义,改引脚时同步修改端口源与引脚源。 |
核心代码解读与移植
示例把一个按键引脚配成外部中断入口,中断到来时在服务程序里翻转 LED。
数据路径: LedInit 配置 LED 引脚 → KeyInputExtiInit 使能 GPIO 时钟并把 PA4 接到 EXTI 线 → EXTI_InitPeripheral 设为下降沿中断 → 按下松开 KEY2 产生下降沿 → EXTI0_6_IRQHandler 翻转 PA7 并清挂起位
1. 主流程只做初始化与点亮。 main 先初始化两个 LED 与按键外部中断,点亮 LED1 后进入空循环,后续动作全部交给中断。
int main(void)
{
/*SystemInit() function has been called by startup file startup_n32g033.s*/
/*Initialize Led1 and Led2 as output pushpull mode*/
LedInit(LED1_PORT, LED1_PIN);
LedInit(LED2_PORT, LED2_PIN);
/*Initialize key as external line interrupt*/
KeyInputExtiInit(KEY_INPUT_PORT, KEY_INPUT_PIN);
/*Turn on Led1*/
LedOn(LED1_PORT, LED1_PIN);
while (1)
{
}
}
LED 与按键的端口、引脚都在 inc/main.h 用宏定义,移植时改宏即可,不必改动主流程。
2. 按键引脚要同时配 GPIO 与 EXTI。 KeyInputExtiInit 使能 GPIO 时钟、把引脚配成上拉输入,用 GPIO_ConfigEXTILine 把引脚接到 EXTI 线,再由 EXTI_InitPeripheral 设置触发沿。
/* Enable the GPIO Clock */
RCC_EnableAPBPeriphClk(RCC_APB_PERIPH_GPIO,ENABLE);
/*Configure the GPIO pin as input floating*/
if (Pin <= GPIO_PIN_ALL)
{
GPIO_InitStruct(&GPIO_InitStructure);
GPIO_InitStructure.Pin = Pin;
GPIO_InitStructure.GPIO_Pull = GPIO_PULL_UP;
GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure);
}
/*Configure key EXTI Line to key input Pin*/
GPIO_ConfigEXTILine(KEY_INPUT_PORT_SOURCE, KEY_INPUT_PIN_SOURCE);
/*Configure key EXTI line*/
EXTI_InitStructure.EXTI_Line = KEY_INPUT_EXTI_LINE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitPeripheral(&EXTI_InitStructure);
/*Set key input interrupt priority*/
NVIC_InitStructure.NVIC_IRQChannel = KEY_INPUT_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = NVIC_PRIORITY_1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
示例把 PA4 接到 EXTI 线,但中断线宏取的是 EXTI_LINE1,两者并不完全对应;移植时按实际引脚同步核对线号、端口源与引脚源。
3. 中断里判断标志、翻转 LED 再清挂起位。 EXTI0_6_IRQHandler 检查对应 EXTI 线的状态标志,翻转 LED2 后清除中断挂起位,避免反复进入中断。
void EXTI0_6_IRQHandler(void)
{
if (RESET != EXTI_GetStatusFlag(KEY_INPUT_EXTI_LINE))
{
LedBlink(LED2_PORT, LED2_PIN);
EXTI_ClrITPendBit(KEY_INPUT_EXTI_LINE);
}
}
中断处理只翻转一次 LED;若要在中断里做更多事,注意把执行时间控制得尽量短。
对应源码: src/main.c、src/n32g033_it.c、firmware/n32g033_std_periph_driver/inc/n32g033_exti.h
5.5.4 注意与排障
| 场景 | 检查与建议 | 来源 |
|---|---|---|
| 触发沿选择 | 用户手册 EXTI 章写明每条 EXTI 线可单独选择上升沿、下降沿或双边沿触发; 确认触发沿与引脚上的实际电平变化一致。 |
用户手册 |
| EXTI 线与引脚映射 | 用户手册 EXTI 章写明外部中断线经由复用功能与 GPIO 引脚关联; 改引脚时同步修改端口源与引脚源。 |
用户手册 |
| 软件触发中断 | 用户手册 EXTI 章写明可用软件方式触发一次中断; 调试时可用它验证中断服务程序能否进入。 |
用户手册 |
| 中断与事件模式 | 用户手册 EXTI 章写明 EXTI 线可工作在中断模式或事件模式; 进入低功耗前按唤醒需求选择模式。 |
用户手册 |
勘误手册 V1.0.0(2025.9.25)针对 A 版芯片,未列出 EXTI 相关条目。