5.7 EXTI Guide

This chapter describes the file composition and the 9 public functions of the EXTI driver in the N32G41x standard peripheral library: reset and initialization of the interrupt lines, reading and clearing of interrupt and event flags and interrupt status, software interrupt generation, and selection of the RTC timestamp trigger source; the example section describes KeyInterrupt. Read the mapping between the 26 interrupt lines and GPIO pins and the edge-trigger and mask configuration together with the Interrupts and events chapter of the user manual, take the pin-to-line mapping from the GPIO and AFIO chapter, and take the errata sheet as the authority on known chip issues.

5.7.1 Related files

Relative path Purpose
firmware/n32g41x_std_periph_driver/inc/n32g41x_exti.h Defines the EXTI_InitType structure, the mode and trigger-edge enumerations and the interrupt-line macros, and declares 9 public functions in the three sections reset and initialization, interrupt and flag management, and configuration
firmware/n32g41x_std_periph_driver/src/n32g41x_exti.c Implements those 9 functions: interrupt-line register reset, mode and trigger-edge writes, software interrupt generation, flag and interrupt-status read and clear, and RTC timestamp trigger source selection
projects/n32g41x_EVAL/examples/EXTI/ EXTI example root directory, holding the single example KeyInterrupt
projects/n32g41x_EVAL/examples/EXTI/KeyInterrupt/ Directory composition of this example: MDK-ARM/, EWARM/, inc/, src/, readme.txt
projects/n32g41x_EVAL/bsp/ Board support files referenced by this example: evaluation-board LED and key definitions and the millisecond delay function

5.7.2 API reference

Search API9 functions

The following 9 public functions are listed in the declaration order of n32g41x_exti.h in 3 groups; each entry gives a summary and the original comment above the function in n32g41x_exti.c.

Reset and initialization

EXTI_DeInit, EXTI_InitPeripheral, EXTI_InitStruct

Interrupt and flag management

EXTI_TriggerSWInt, EXTI_GetStatusFlag, EXTI_ClrStatusFlag, EXTI_GetITStatus, EXTI_ClrITPendBit

Configuration RTC timestamp

EXTI_RTCTimeStampSel

void EXTI_DeInit(void)Reset the EXTI registers.
Source comment
name    EXTI_DeInit.
fun     Reset the EXTI registers.
return  none

Use note: The implementation clears EXTI->IMASK, EXTI->EMASK, EXTI->RT_CFG and EXTI->FT_CFG in turn, then writes EXTI_LINEALL (0x03FFFFFF) to EXTI->PEND to clear all pending bits.

void EXTI_InitPeripheral(const EXTI_InitType *EXTI_InitParam)Initializes the EXTI according to EXTI_InitType.
Source comment
name    EXTI_InitPeripheral.
fun     Initializes the EXTI according to EXTI_InitType.
param   EXTI_InitParam(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_LINE25
          - 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

Use note: When EXTI_LineCmd is not DISABLE the implementation first clears the enable and edge-configuration bits of the line and then sets them according to EXTI_Mode and EXTI_Trigger; an EXTI_Mode or EXTI_Trigger value outside the enumeration leaves the corresponding enable or edge register unchanged.

void EXTI_InitStruct(EXTI_InitType *EXTI_StructInit)Fills each EXTI_InitType member with its default value.
Source comment
name    EXTI_InitStruct.
fun     Fills each EXTI_InitType member with its default value.
param   EXTI_StructInit : Pointer to the EXTI_InitType structure to be initialized.
return  none
void EXTI_TriggerSWInt(uint32_t EXTI_Line)Generates a Software interrupt.
Source comment
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
            - EXTI_LINE25
return  none
FlagStatus EXTI_GetStatusFlag(uint32_t EXTI_Line)Get EXTI line flag status.
Source comment
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
            - EXTI_LINE25
return  SET or RESET
void EXTI_ClrStatusFlag(uint32_t EXTI_Line)Clear EXTI line flag status.
Source comment
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
            - EXTI_LINE25
return  none
INTStatus EXTI_GetITStatus(uint32_t EXTI_Line)GET EXTI line interrupt status.
Source comment
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
            - EXTI_LINE25
return  SET or RESET

Use note: The implementation returns SET only when the bit of EXTI->PEND is set and the matching bit of EXTI->IMASK is enabled, unlike EXTI_GetStatusFlag, which reads EXTI->PEND alone.

void EXTI_ClrITPendBit(uint32_t EXTI_Line)Clear EXTI line interrupt pend bit.
Source comment
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
            - EXTI_LINE25
return  none

Use note: The implementation is identical to EXTI_ClrStatusFlag: both write EXTI_Line to EXTI->PEND.

void EXTI_RTCTimeStampSel(uint32_t EXTI_TSSEL_Line)Select one of EXTI inputs to the RTC TimeStamp event.
Source comment
name    EXTI_RTCTimeStampSel.
fun     Select one of EXTI inputs to the RTC TimeStamp event.
param   EXTI_TSSEL_Line(The input parameters must be the following values) :
            - 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

Use note: The implementation read-modify-writes EXTI->TS_SEL, clearing EXTI_TSSEL_LINE_MASK (the low 4 bits) first and then writing EXTI_TSSEL_Line, so it can select only one of EXTI0 to EXTI15.

5.7.3 Demo descriptions

This section describes the single EXTI example: KeyInterrupt uses the falling edges of two keys to trigger the EXTI4 and EXTI5 interrupts, the interrupt handlers switch the current LED, and the main loop blinks that LED and prints the current key.

5.7.3.1 KeyInterrupt key interrupt

Example directory: projects/n32g41x_EVAL/examples/EXTI/KeyInterrupt/

Initialize the print UART→Configure LED1 and LED2 as push-pull outputs and KEY1 and KEY2 as pull-up inputs→Map the KEY1 and KEY2 pins to EXTI lines and configure them as falling-edge interrupts→Enable the EXTI4 and EXTI5_9 interrupt channels→Blink the LED for the current key and print the key in the main loop

Item Source analysis
Function Pressing KEY1 (PA4) triggers the EXTI4 interrupt and pressing KEY2 (PA5) triggers the EXTI5 interrupt;
the interrupt handlers switch the current LED, and the main loop blinks that LED and prints the current key on the serial port.
Source files src/main.c: main, EXTI_KEY_Configuration and the LED and KEY helper functions;
src/n32g41x_it.c: the EXTI4 and EXTI5_9 interrupt handlers and the other vectors;
inc/main.h: MAX_LED_KEY_CNT and the LED and KEY function declarations;
inc/n32g41x_it.h: the interrupt function declarations;
readme.txt: function, environment and usage;
MDK-ARM/, EWARM/: the Keil and IAR projects.
Key configuration LED1 is PA1 and LED2 is PA7, both configured as GPIO_MODE_OUTPUT_PP, GPIO_NO_PULL, GPIO_DS_HIGH and GPIO_SLEW_RATE_FAST;
KEY1 is PA4 and KEY2 is PA5, configured as GPIO_MODE_INPUT with GPIO_PULL_UP, with Bit_RESET as the pressed level.
KEY1 uses EXTI_LINE4, EXTI_Mode_Interrupt and EXTI_Trigger_Falling on channel EXTI4_IRQn;
KEY2 uses EXTI_LINE5 on channel EXTI5_9_IRQn, and both channels use preemption priority 0 and subpriority 0.
The system clock is HSI+PLL, 80 MHz for N32G412 and 96 MHz for N32G415;
the print UART is PA9 at 115200 bps.
Program and data path main calls log_init and prints EXTI key interrupt demo!, initializes the peripherals with LED_Init and KEY_Init, then calls EXTI_KEY_Configuration;
a key press makes EXTI4_IRQHandler set key_cnt to 0 or EXTI5_9_IRQHandler set it to 1 and set exti_int to 1;
while exti_int is non-zero the main loop prints str[key_cnt] and the LED number, then toggles LedPort[key_cnt] with LED_Blink.
Main APIs EXTI_InitStruct, EXTI_InitPeripheral, EXTI_GetStatusFlag, EXTI_ClrITPendBit, GPIO_ConfigEXTILine, NVIC_Init
Verification After reset the serial port prints EXTI key interrupt demo! and LED1 blinks;
pressing KEY1 makes LED1 blink and prints KEY1(PA4), while pressing KEY2 makes LED2 blink and prints KEY2(PA5).
Use note KEY1 (PA4) reaches EXTI4_IRQn through EXTI_LINE4 and KEY2 (PA5) reaches EXTI5_9_IRQn through EXTI_LINE5;
the keys are pull-up inputs that read low when pressed, which is why the trigger is the falling edge.
Supported devices are N32G412x8L7, N32G412xBL7, N32G415x8L7 and N32G415xBL7;
the development environment is KEIL MDK-ARM 5.34 or IAR EWARM 8.50.1.
Core-code walkthrough and porting

The example takes the LED pins from the board-level macros, wires the GPIO pins to EXTI lines and enables the interrupt channels step by step, and finally switches the LED in the interrupt and in the main loop.

Data path: EXTI_KEY_Configuration -> GPIO_ConfigEXTILine maps PA4 and PA5 -> EXTI_InitStruct applies the defaults -> EXTI_InitPeripheral writes the mode and trigger edge of EXTI_LINE4 and EXTI_LINE5 -> NVIC_Init enables the interrupt channels -> a key falling edge -> EXTI4_IRQHandler and EXTI5_9_IRQHandler update key_cnt and exti_int -> the main loop calls LED_Blink and prints

1. The board-level macros give the LED pins. The evaluation-board LED ports, pins and clocks are defined in the BSP header, and the example refers to them through the LED1_PORT, LED1_PIN and similar macros; both the interrupt and the main loop use this set of macros to locate the LEDs.

projects/n32g41x_EVAL/bsp/inc/n32g41x_stb.hn32g41x_stb.h
/* LED defines ------------------------------------------------------------------*/
#define LED1_STB
#define LED1_PORT                      GPIOA
#define LED1_PIN                       GPIO_PIN_1
#define LED1_CLOCK                     RCC_AHB_PERIPH_GPIO
#define LED1_CLOCK_ENABLE              RCC_EnableAHBPeriphClk(LED1_CLOCK, ENABLE)
#define LED1_ON_STATE                  Bit_SET

#define LED2_STB
#define LED2_PORT                      GPIOA
#define LED2_PIN                       GPIO_PIN_7
#define LED2_CLOCK                     RCC_AHB_PERIPH_GPIO
#define LED2_CLOCK_ENABLE              RCC_EnableAHBPeriphClk(LED2_CLOCK, ENABLE)
#define LED2_ON_STATE                  Bit_SET

Changing the board or the LED pins requires only these macros; the example code stays the same.

2. The GPIO pins are mapped to EXTI lines and initialized. EXTI_KEY_Configuration first applies the defaults with EXTI_InitStruct, maps PA4 to EXTI4 and enables it in interrupt mode on the falling edge; KEY2 reuses the same structure and only changes the line number.

src/main.csrc/main.c · EXTI_KEY_Configuration
    EXTI_InitType EXTI_InitStructure;
    NVIC_InitType NVIC_InitStructure;

    EXTI_InitStruct(&EXTI_InitStructure);

    /* Configure KEY1 PA4 -> EXTI_LINE4 */
    GPIO_ConfigEXTILine(GPIOA_PORT_SOURCE, GPIO_PIN_SOURCE4);

    EXTI_InitStructure.EXTI_Line    = EXTI_LINE4;
    EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_InitPeripheral(&EXTI_InitStructure);

    /* Configure KEY2 PA5 -> EXTI_LINE5 */
    GPIO_ConfigEXTILine(GPIOA_PORT_SOURCE, GPIO_PIN_SOURCE5);
    EXTI_InitStructure.EXTI_Line    = EXTI_LINE5;
    EXTI_InitPeripheral(&EXTI_InitStructure);

The mapping call GPIO_ConfigEXTILine belongs to the GPIO driver, so porting to other pins means changing both the pin source and EXTI_Line.

3. The two EXTI interrupt channels are enabled. After the interrupt lines are enabled the matching channels must also be opened in the NVIC; PA4 and PA5 fall on the independent channel EXTI4_IRQn and the shared channel EXTI5_9_IRQn respectively.

src/main.csrc/main.c · EXTI_KEY_Configuration
    /* Enable EXTI4 interrupt */
    NVIC_InitStructure.NVIC_IRQChannel                   = EXTI4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRE_PRIORITY_0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = NVIC_SUB_PRIORITY_0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* Enable EXTI5_9 interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI5_9_IRQn;
    NVIC_Init(&NVIC_InitStructure);

Porting to other interrupt lines means changing NVIC_IRQChannel according to the vector table of the user manual; EXTI10 to EXTI15, for example, share EXTI15_10_IRQn.

4. The interrupt handlers switch the key and clear the pending bit. Both handlers first test the flag, then change the current key index, and finally write the line number to EXTI_PEND to clear the pending bit.

src/n32g41x_it.csrc/n32g41x_it.c · EXTI4_IRQHandler
void EXTI4_IRQHandler(void)
{
    if (EXTI_GetStatusFlag(EXTI_LINE4) != RESET)
    {
        LED_Off(LedPort[key_cnt], LedPin[key_cnt]);
        key_cnt = 0;
        exti_int = 1;
        EXTI_ClrITPendBit(EXTI_LINE4);
    }
}
src/n32g41x_it.csrc/n32g41x_it.c · EXTI5_9_IRQHandler
void EXTI5_9_IRQHandler(void)
{
    if (EXTI_GetStatusFlag(EXTI_LINE5) != RESET)
    {
        LED_Off(LedPort[key_cnt], LedPin[key_cnt]);
        key_cnt = 1;
        exti_int = 1;
        EXTI_ClrITPendBit(EXTI_LINE5);
    }
}

Each handler clears only the pending bit of its own line; when several lines are enabled at once, every line must be tested and cleared in turn.

5. The main loop blinks and prints according to the current key. The main loop only checks the exti_int flag: while it is non-zero the loop prints the current key and clears the flag, then keeps toggling LedPort[key_cnt].

src/main.csrc/main.c · main
    while (1)
    {
        if(exti_int != 0)
        {
            printf("Current key: %s, LED%lu blinking\r\n", str[key_cnt], (unsigned long)(key_cnt + 1));
            exti_int = 0;
        }
        LED_Blink(LedPort[key_cnt], LedPin[key_cnt]);
        SysTick_Delay_Ms(500);
    }

To change the blink rate, change the argument of SysTick_Delay_Ms; to change the LED-to-key mapping, change the value assigned to key_cnt in the interrupt.

Corresponding source files: src/main.c, src/n32g41x_it.c, projects/n32g41x_EVAL/bsp/inc/n32g41x_stb.h

5.7.4 Notes and troubleshooting

Scenario Check & action Source
Generating an external interrupt from a GPIO pin The Interrupts and events chapter of the user manual states that the AFIO clock must be enabled before an AFIO EXTI configuration register maps a GPIO line to an interrupt, and the GPIO and AFIO chapter requires the port to be configured as an input. User manual
An EXTI line is configured but no interrupt is generated Besides enabling the line in EXTI_IMASK, the matching NVIC interrupt channel must also be enabled;
EXTI0 to EXTI4 each have their own channel, EXTI5 to EXTI9 share the EXTI5_9 channel and EXTI10 to EXTI15 share the EXTI15_10 channel.
User manual
EXTI lines driven by internal modules EXTI16 to EXTI19 are connected to the PVD and to the RTC alarm, timestamp and wakeup events, while EXTI20 to EXTI25 are connected to BTIM1, COMP1 to COMP3 and USART1 and USART4;
a note in the manual states that EXTI20 to EXTI25 support the rising edge only.
User manual
Clearing an interrupt request Write 1 to the matching bit of EXTI_PEND to clear the pending request;
changing the edge-detection polarity also clears that bit.
User manual
Reserved bits Bits 31:26 of EXTI_EMASK, EXTI_IMASK, EXTI_RT_CFG, EXTI_FT_CFG, EXTI_PEND and EXTI_SWIE, and bits 31:4 of EXTI_TS_SEL, are reserved and must keep their reset values. User manual

The N32G412 and N32G415 series errata sheet V1.0.0 (2026.6.30) lists a single row for revision A chips with an empty errata link column, and gives no specific entries.

Nations Technologies DevKit Docs

Datasheets, SDK, driver APIs and demo guides for Nations Technologies MCU development kits, organized by chip series.

© 2026 Nations Technologies Inc. All rights reserved.粤ICP备11069485号This site uses cookie-free anonymous analytics.