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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
/* 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.
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.
/* 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.
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);
}
}
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].
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.