Implementing External Interrupts (EXTI) on STM32 with Standard Peripheral Library

External interrupts allow a microcontroller to respond immediately too external events by pausing its current program execution, handling the interrupt request, and then resuming normal operation. The STM32 EXTI controller manages up to 20 interrupt/event lines, with GPIO pins 0-15 connected to EXTI lines 0-15. Additional lines serve specific purposes: EXTI_Line16 connects to the PVD output, EXTI_Line17 to RTC alarms, EXTI_Line18 to USB wake-up events, and EXTI_Line19 to Ethernet wake-up events.

Configuring GPIO pins for external interrupt functionality involves these steps:

  1. Enable the relevant clock signals
  2. Set up the GPIO pin mode
  3. Configure NVIC interrupts and assign priorities
  4. Initialize the EXTI peripheral
  5. Enable interrupts and clear any pending flags
  6. Implement the interrupt service routine

Any GPIO pin on STM32 microcontrollers can be configured to trigger external interrupts.

Code Impleemntation

Key_Handler.c

#include "stm32f10x.h"
#include "Delay.h"
#include "Key_Handler.h"

uint8_t Key_Press_Status;

static void Setup_NVIC(void)
{
    NVIC_InitTypeDef NVIC_Config;
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    
    NVIC_Config.NVIC_IRQChannel = BUTTON_EXTI_IRQn;
    NVIC_Config.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_Config.NVIC_IRQChannelSubPriority = 1;
    NVIC_Config.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_Config);
}

void Initialize_Button(void)
{
    GPIO_InitTypeDef GPIO_Config;
    EXTI_InitTypeDef EXTI_Config;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
    
    Setup_NVIC();
    
    GPIO_Config.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Config.GPIO_Pin = BUTTON_PIN;
    GPIO_Config.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_Config);
    
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, BUTTON_PIN_SOURCE);
    EXTI_Config.EXTI_Line = BUTTON_EXTI_LINE;
    EXTI_Config.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_Config.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_Config.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_Config);
    
    EXTI_ClearITPendingBit(BUTTON_EXTI_LINE);
}

void EXTI15_10_IRQHandler(void)
{
    if(EXTI_GetITStatus(BUTTON_EXTI_LINE) != RESET)
    {
        Delay_ms(10);
        if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13) == RESET)
        {
            Key_Press_Status = 1;
        }
        EXTI_ClearITPendingBit(BUTTON_EXTI_LINE);
    }
}

Key_Handler.h

#ifndef KEY_HANDLER_H
#define KEY_HANDLER_H

#include "stm32f10x.h"
#include "main.h"

#define BUTTON_PORT              GPIOB
#define BUTTON_CLOCK             (RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO)
#define BUTTON_PIN               GPIO_Pin_13
#define BUTTON_PORT_SOURCE       GPIO_PortSourceGPIOB
#define BUTTON_PIN_SOURCE        GPIO_PinSource13
#define BUTTON_EXTI_LINE         EXTI_Line13
#define BUTTON_EXTI_IRQn         EXTI15_10_IRQn
#define BUTTON_IRQ_HANDLER       EXTI15_10_IRQHandler

void Initialize_Button(void);

#endif

Tags: STM32 External Interrupt EXTI gpio NVIC

Posted on Thu, 11 Jun 2026 17:08:35 +0000 by developerdave