STM32_EXTI_HAL - GitMasterNikanjam/ARM_WiKi GitHub Wiki

Configuration:

GPIO mode:                Rising edge/Falling edge/Change
GPIO Pull-up/Pull-down:   Nothing/Pull-up/Pull-down

Important Defines and Functions

//IO operation functions *****************************************************/
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

//brief  This function handles EXTI interrupt request.
//param  GPIO_Pin Specifies the pins connected EXTI line
//retval None
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	
	switch(GPIO_Pin)
	{
		case GPIO_PIN_0:
                 // Do somthing
		break;
		case GPIO_PIN_1:
			
		break;
		case GPIO_PIN_2:
			
		break;
		case GPIO_PIN_3:
			
		break;
		case GPIO_PIN_4:
			
		break;
		case GPIO_PIN_5:
			
		break;
		case GPIO_PIN_6:
			
		break;
		case GPIO_PIN_7:
			
		break;
		case GPIO_PIN_8:
			
		break;
		case GPIO_PIN_9:
			
		break;
		case GPIO_PIN_10:
			
		break;
		case GPIO_PIN_11:
			
		break;
		case GPIO_PIN_12:
			
		break;
		case GPIO_PIN_13:
			
		break;
		case GPIO_PIN_14:
			
		break;
		case GPIO_PIN_15:

		break;
			
	}	
}

The STM32F407VGT6 microcontroller supports multiple external interrupts through its GPIO pins and EXTI (External Interrupt) peripheral. Here's a breakdown:

1. EXTI Lines:

  • The STM32F407VGT6 has 16 EXTI lines (EXTI0 to EXTI15).
  • Each EXTI line can be mapped to one GPIO pin from any GPIO port (e.g., PA0, PB0, PC0 for EXTI0).

2. GPIO Pins as Interrupt Sources:

  • All GPIO pins can potentially be configured as external interrupt sources, but they need to share the EXTI lines.
  • For example, if EXTI0 is assigned to PA0, it cannot simultaneously be used for PB0 or PC0.

3. Special EXTI Lines:

  • EXTI16: Connected to the PVD (Programmable Voltage Detector).
  • EXTI17: Connected to the RTC Alarm.
  • EXTI18: Connected to the USB OTG FS Wakeup.
  • EXTI19: Connected to the Ethernet Wakeup.
  • EXTI20: Connected to the USB OTG HS Wakeup.

4. Interrupt Priorities:

  • The NVIC (Nested Vector Interrupt Controller) allows you to configure the priority of these interrupts.
  • You can define priorities for efficient handling in applications with multiple concurrent interrupts.

Summary:

The STM32F407VGT6 can use 16 EXTI lines for GPIO-based external interrupts, plus additional lines for specialized peripherals (like PVD, RTC, USB, etc.). If more interrupt sources are needed, techniques like pin sharing or using timer/counter capture inputs can be employed.


In STM32 microcontrollers, the preemption priority and sub-priority are used to manage the Nested Vector Interrupt Controller (NVIC) priorities for interrupt handling. These concepts determine how interrupts are prioritized and resolved when multiple interrupts occur simultaneously or when an interrupt occurs during the execution of another.

1. Preemption Priority:

  • Definition: Preemption priority defines the interrupt priority level that determines if one interrupt can interrupt (preempt) another.
  • Behavior:
    • A lower numerical value indicates a higher priority.
    • If an interrupt with a higher preemption priority occurs while a lower priority interrupt is being executed, the higher-priority interrupt will preempt the lower one.
  • Example:
    • Interrupt A: Preemption priority 1.
    • Interrupt B: Preemption priority 2.
    • If both interrupts are triggered, Interrupt A will preempt Interrupt B.

2. Sub-Priority:

  • Definition: Sub-priority determines the order of execution within the same preemption priority level if multiple interrupts are pending.
  • Behavior:
    • If two interrupts have the same preemption priority, the one with the lower sub-priority value will be handled first.
    • Sub-priority does not affect preemption; it only resolves priority conflicts at the same preemption level.
  • Example:
    • Interrupt A: Preemption priority 1, Sub-priority 0.
    • Interrupt B: Preemption priority 1, Sub-priority 1.
    • Both have the same preemption priority, but Interrupt A will execute first due to its lower sub-priority.

3. Priority Grouping:

  • The NVIC uses a priority grouping scheme to divide the priority levels between preemption priority and sub-priority.
  • Priority grouping determines how many bits are assigned to each type of priority:
    • Group 0: All bits for sub-priority, no preemption priority.
    • Group 4: Equal bits for preemption and sub-priority.
    • Group 7: All bits for preemption priority, no sub-priority.
  • In STM32CubeMX, this can be configured using the NVIC Priority Group option.

4. Configuration in STM32CubeMX:

  • In STM32CubeMX, you can set the preemption priority and sub-priority for each interrupt in the NVIC Configuration section.
  • Example:
    • TIM1 Update Interrupt: Preemption Priority = 0, Sub-priority = 1.
    • USART1 Interrupt: Preemption Priority = 1, Sub-priority = 0.
    • This means the TIM1 interrupt has higher preemption priority and can interrupt the USART1 interrupt.

5. Summary of Effects:

  • Preemption Priority:
    • Controls if an interrupt can interrupt another currently executing interrupt.
  • Sub-Priority:
    • Resolves conflicts when two interrupts with the same preemption priority are pending.

By carefully managing these priorities, you can ensure that critical interrupts are handled promptly while maintaining control over the interrupt system's behavior.


In STM32CubeMX, the "Enabled" checkbox in the NVIC configuration section is used to enable or disable the initialization of interrupt settings for a specific peripheral.

What It Does:

When the Enabled checkbox for NVIC is selected:

  1. Interrupt Activation: The interrupt for the selected peripheral is enabled in the NVIC (Nested Vector Interrupt Controller).
  2. Priority Configuration: STM32CubeMX generates code to configure the preemption priority and sub-priority for the interrupt.
  3. Interrupt Vector: The interrupt handler function for the peripheral is included in the generated code, making it ready to handle interrupts triggered by the peripheral.

When the Enabled checkbox is not selected:

  1. The interrupt for that peripheral will not be enabled in the NVIC.
  2. No priority configuration or interrupt initialization code will be generated for that peripheral.
  3. The interrupt handler function for the peripheral will not be generated, meaning interrupts from the peripheral won't trigger any response unless manually configured later.

When to Enable NVIC for a Peripheral:

  • Enable it when:
    • The peripheral needs to generate interrupts, such as a timer, UART, ADC, or external GPIO interrupts.
    • You want the interrupt to be handled by an ISR (Interrupt Service Routine).
  • Disable it when:
    • The peripheral will be polled instead of using interrupts (e.g., manually checking flags in the program).
    • You don't want the peripheral to trigger any interrupt.

Example:

Peripheral Configuration: Timer (TIM2)

  1. NVIC "Enabled" is checked:

    • STM32CubeMX generates:
      • Initialization code for TIM2 in HAL_TIM_Base_MspInit().
      • Configures the interrupt in NVIC (priority and sub-priority).
      • Adds the TIM2_IRQHandler() function to handle interrupts.
    • TIM2 can generate interrupts, and the handler will execute when the interrupt is triggered.
  2. NVIC "Enabled" is unchecked:

    • No code is generated to configure NVIC for TIM2.
    • You can still use TIM2 in polling mode, but its interrupts won't work unless you manually configure the NVIC later.

In Summary:

The Enabled checkbox in STM32CubeMX for NVIC determines whether the software will configure and handle interrupts for a given peripheral. It ensures that the NVIC is correctly set up for peripherals requiring interrupt-based operation.


To use a custom function when an external interrupt occurs on a specific pin in an STM32 project (configured using STM32CubeMX), follow these steps:


1. Configure the External Interrupt in STM32CubeMX

  1. Open STM32CubeMX.
  2. Go to the Pinout & Configuration tab.
  3. Assign the desired pin (e.g., PA0) to GPIO_EXTIxx (where xx corresponds to the EXTI line, such as EXTI0 for PA0).
  4. Enable the NVIC checkbox for the corresponding EXTI interrupt in the Configuration tab.
  5. Optionally, set the Interrupt Priority and Sub-priority.
  6. Generate the code by clicking Generate Code.

2. Add Your Custom Function

  1. Open the generated project in your IDE (e.g., STM32CubeIDE).

  2. Locate the interrupt handler in stm32f4xx_it.c. For example, if using EXTI0, look for the function:

    void EXTI0_IRQHandler(void)
    {
        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
    }
  3. The HAL_GPIO_EXTI_IRQHandler() function calls the weak HAL_GPIO_EXTI_Callback() function. This is where you can place your custom logic.


3. Override the HAL_GPIO_EXTI_Callback()

In your main .c file (e.g., main.c), implement the HAL_GPIO_EXTI_Callback() function:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_0) // Check the specific pin
    {
        // Call your custom function
        MyCustomFunction();
    }
}

Replace GPIO_PIN_0 with the pin number corresponding to your interrupt.


4. Write Your Custom Function

Define your custom function, for example:

void MyCustomFunction(void)
{
    // Custom logic here
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); // Example: Toggle an LED
}

5. Verify NVIC Configuration

Ensure the NVIC is correctly configured to handle the EXTI interrupt. This is automatically done by STM32CubeMX, but you can verify the following code in main.c or stm32f4xx_hal_msp.c:

HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);

6. Compile and Test

  1. Build the project and flash it to your STM32 microcontroller.
  2. Trigger the interrupt by applying the appropriate signal (e.g., toggling the pin to the configured edge—rising or falling).

Key Points

  • The HAL_GPIO_EXTI_Callback() function is designed for user code and should be used to avoid modifying the interrupt handler directly.
  • Always check the GPIO_Pin argument in HAL_GPIO_EXTI_Callback() to ensure your logic applies to the correct pin.
  • Use debounce techniques or filters if your signal might have noise.

This approach allows you to seamlessly integrate custom behavior for specific external interrupts while maintaining compatibility with the STM32 HAL framework.


When an external interrupt occurs on an STM32 microcontroller, a series of hardware and software events are triggered to handle the interrupt. Here's a step-by-step breakdown of what happens:


1. Hardware Level: Interrupt Detection

  1. Pin Event Detection:

    • The external signal (e.g., a rising edge, falling edge, or both) is detected on the GPIO pin configured as an external interrupt source.
  2. EXTI Line Trigger:

    • The signal is routed to the corresponding EXTI line (e.g., EXTI0 for PA0).
    • The EXTI hardware compares the signal with its configured trigger condition (rising, falling, or both).
    • If the trigger condition matches, the EXTI line asserts an interrupt request (IRQ) to the Nested Vector Interrupt Controller (NVIC).
  3. NVIC Interrupt Request:

    • The NVIC receives the IRQ from the EXTI line and checks the interrupt's preemption priority and sub-priority.
    • If the interrupt has the highest priority among pending interrupts, the NVIC:
      • Suspends the current code execution (if not in a critical section or higher-priority interrupt).
      • Jumps to the interrupt vector table to execute the corresponding Interrupt Service Routine (ISR).

2. Software Level: Interrupt Handling

  1. Interrupt Handler Execution:

    • The CPU jumps to the corresponding interrupt handler function, defined in the startup file (e.g., startup_stm32f407xx.s).

    • For example, for EXTI0 (PA0), the handler is:

      void EXTI0_IRQHandler(void)
      {
          HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
      }
      
  2. HAL Function Handling:

    • The HAL_GPIO_EXTI_IRQHandler() function is called. It is part of the HAL library and performs generic EXTI interrupt processing.

    • It determines which EXTI line triggered the interrupt and calls the user-defined callback function.

      void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
      {
          if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
          {
              __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); // Clear the interrupt flag
              HAL_GPIO_EXTI_Callback(GPIO_Pin);  // Call user-defined callback
          }
      }
      
  3. User Callback Execution:

    • The weak function HAL_GPIO_EXTI_Callback() is called. This is where user-defined actions are implemented. For example:

      void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
      {
          if (GPIO_Pin == GPIO_PIN_0)
          {
              MyCustomFunction(); // Custom user function
          }
      }
      
  4. Custom Function Execution:

    • The user-defined function (e.g., MyCustomFunction()) executes the desired application logic, such as toggling an LED, sending data, or initiating a response.

3. Return to Normal Execution

  1. Return from ISR:
    • Once the ISR completes, the CPU restores the previous context and resumes normal code execution where it was interrupted.
    • If higher-priority interrupts are pending, the CPU may jump to their ISRs first.

Summary of Function Execution Flow

  1. Interrupt Triggered:
    • Hardware detects an external interrupt (e.g., EXTI0).
  2. NVIC Handler:
    • CPU jumps to EXTI0_IRQHandler().
  3. HAL Driver:
    • HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0) is executed.
  4. Callback:
    • HAL_GPIO_EXTI_Callback(GPIO_PIN_0) is called by the HAL.
  5. Custom Logic:
    • User-defined function (e.g., MyCustomFunction()) runs.
  6. Return:
    • Control returns to the interrupted program.

Visual Representation of Flow:

Level Action Code Example
Hardware EXTI detects event, sends IRQ to NVIC N/A
NVIC NVIC triggers interrupt handler EXTI0_IRQHandler()
HAL Function Handles generic EXTI processing HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0)
Callback Calls user-defined callback HAL_GPIO_EXTI_Callback(GPIO_PIN_0)
Custom Code Executes custom user logic MyCustomFunction()

By following these steps, the system ensures that external interrupts are efficiently handled and the appropriate user-defined actions are executed.

⚠️ **GitHub.com Fallback** ⚠️