External Interrupt using Registers

This is another tutorial in the Register based programming series and today we will see how can we use the external interrupt in STM32. This tutorial will also introduce the working with interrupts in STM32

I am going to focus on F4 and F1 series here. The code will be mainly written for F4 series, but wherever the changes are needed according to the F1 series, I will include them also

Let’s start by configuration first


GPIO Configuration

First of all we will start with configuring the GPIO. I have already covered this for the F4 series and the F1 Series in my previous Tutorial, STM32 GPIO INPUT Configuration

Go to the above link, and see the configuration part.

INTERRUPT Configuration

We need to configure the External Interrupt and to do so, the steps are shown below

	/*************>>>>>>> STEPS FOLLOWED <<<<<<<<************
	1. Enable the SYSCFG/AFIO bit in RCC register 
	2. Configure the EXTI configuration Register in the SYSCFG/AFIO
	3. Disable the EXTI Mask using Interrupt Mask Register (IMR)
	4. Configure the Rising Edge / Falling Edge Trigger
	5. Set the Interrupt Priority
	6. Enable the interrupt

Let’s cover them one by one

1. Enable the SYSCFG/AFIO Bit

This bit will enable the configuration controller clock. In F4 series, we can do this by enabling the SYSCFG bit in the RCC_APB2ENR Register

RCC->APB2ENR |= (1<<14);  // Enable SYSCNFG

In F1 Series, we need to enable the AFIO bit in the RCC_APB2ENR Register

RCC->APB2ENR |= (1<<0);  // Enable AFIO CLOCK

2. Configure the EXTI configuration Register

In the F4 Series, External Interrupt Configuration can be found in the SYSCFG Registers. These EXTI configuration Registers are divided into 4 groups


Since we are using PA1, we will be using SYSCFG_EXTICR1.

As you can see above, to configure the EXTI line for PA1, we need to modify bits 7:6:5:4 with 0:0:0:0

SYSCFG->EXTICR[0] &= ~(0xf<<4);  // Bits[7:6:5:4] = (0:0:0:0)  -> configure EXTI1 line for PA1

Similarly in F1 series, instead of SYSCFG, we have AFIO Registers. Rest of the logic and the code is identical

AFIO->EXTICR[0] &= ~(0xf<<4);  // Bits[7:6:5:4] = (0:0:0:0)  -> configure EXTI1 line for PA1

3. Disable the EXTI Mask

Now onwards the steps will be common for the F4 and F1 series. Here we will disable the mask for the respective pin. This can be done by modifying the Interrupt Mask Register (EXTI_IMR)

As you can see above, in order to disable the mask from a particular pin, we need to write a ‘1’ in the respective location.

EXTI->IMR |= (1<<1);  // Bit[1] = 1  --> Disable the Mask on EXTI 1

4. Configure the Rising/Falling Edge Trigger

We can configure either we want the interrupt to trigger on the rising edge, or the falling edge of the input signal. These configuration can be controlled in the Rising trigger Selection Register (EXTI_RTSR) and the Falling trigger selection register (EXTI_FTSR).

I am selecting the Rising trigger for this tutorial, so I will enable the Rising trigger and Disable the Falling trigger

EXTI->RTSR |= (1<<1);  // Enable Rising Edge Trigger for PA1
EXTI->FTSR &= ~(1<<1);  // Disable Falling Edge Trigger for PA1

5. Set the Interrupt Priority and Enable the Interrupt

Well to do this, we need to use some predefined NVIC functions and you can see them below

NVIC_SetPriority (EXTI1_IRQn, 1);  // Set Priority
NVIC_EnableIRQ (EXTI1_IRQn);  // Enable Interrupt

Here 1 is the priority for the EXTI1 Interrupt. Basically lower the value, highest is the priority. So here I am keeping this priority pretty high.

This completes the configuration for the Interrupt. Now before going to the main code, let’s see the IRQ Handler


The steps to handle the Interrupt are shown below

	/*************>>>>>>> STEPS FOLLOWED <<<<<<<<************
	1. Check the Pin, which trgerred the Interrupt
	2. Clear the Interrupt Pending Bit

To check and clear the Interrupt Pending bit, we need to see the interrupt pending register (EXTI_PR)

This Pending Register bit is set whenever the interrupt is triggered.

if (EXTI->PR & (1<<1))    // If the PA1 triggered the interrupt
        flag = 1;
	EXTI->PR |= (1<<1);  // Clear the interrupt flag by writing a 1 
  • Here we will check if the interrupt is triggered by the pin PA1. This can be done by checking the pending bit in EXTI_PR
  • Next we will perform the operation and clear the bit by writing a ‘1’ in the respective bit
  • Here I am just setting a flag, and the rest of the code will be handled in the main function

The MAIN Function

int main ()
	GPIO_Config ();
	Interrupt_Config ();
	while (1)
		if (flag)
			Delay_ms(100);  // avoid debouncing
			flag = 0;
  • As you can see above, after initializing everything we will check if the flag is set
  • This flag will be set whenever the interrupt is triggered
  • Then we will wait for few milliseconds for the debouncing
  • Next increment the counter and reset the flag again


Check out the VIDEO Below
Notify of
Inline Feedbacks
View all comments