DEV Community

Hedy
Hedy

Posted on

How to optimize interrupt response time for STM32F407 + Sensor Trigger?

Scenario: STM32F407 + Sensor Trigger (e.g., motion, ultrasonic, etc.)
You likely use GPIO (EXTI), timers, or ADC interrupts to process a sensor event. The goal is to make your ISR as fast and efficient as possible so you can respond in real-time and avoid missing further events.

Image description

Step-by-Step Optimization for STM32F407
1. Use EXTI (External Interrupt) Properly
If your sensor triggers via a GPIO pin:

  • Configure EXTI line to the correct edge (rising/falling).
  • Clear pending bit early in the ISR to avoid re-entry:
c void EXTI1_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line1) != RESET) { EXTI_ClearITPendingBit(EXTI_Line1); // ✅ Clear interrupt first sensor_event_flag = 1; // ✅ Set a flag, keep ISR short } } 
Enter fullscreen mode Exit fullscreen mode

2. Assign EXTI a High Priority in NVIC
Lower number = higher priority.

c NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // Highest NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); 
Enter fullscreen mode Exit fullscreen mode

3. Keep the ISR Fast — Use a Flag
Never process sensor data inside the ISR. Just set a flag and handle it in the main loop or RTOS task.

c volatile uint8_t sensor_event_flag = 0; int main(void) { while (1) { if (sensor_event_flag) { sensor_event_flag = 0; process_sensor_data(); // Safe to do here } } } 
Enter fullscreen mode Exit fullscreen mode

4. If the Sensor Uses ADC or PWM Capture: Use DMA
For ADC sampling (e.g., analog sensor):
Use DMA + interrupt to offload CPU:

c // Configure ADC + DMA ADC_Init(); DMA_Init(); // Enable interrupt on DMA transfer complete DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE); 
Enter fullscreen mode Exit fullscreen mode

ISR:

c void DMA2_Stream0_IRQHandler(void) { if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)) { DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0); adc_ready = 1; } } 
Enter fullscreen mode Exit fullscreen mode

5. Profile with GPIO Pin Toggle
To measure real ISR timing:

c void EXTI1_IRQHandler(void) { GPIO_SetBits(GPIOB, GPIO_Pin_1); // Start timing EXTI_ClearITPendingBit(EXTI_Line1); sensor_event_flag = 1; GPIO_ResetBits(GPIOB, GPIO_Pin_1); // End timing } 
Enter fullscreen mode Exit fullscreen mode

Then use an oscilloscope or logic analyzer to measure timing from signal edge → GPIO toggle.

6. Use STM32-Specific Tools

  • CubeMX: Easily configure EXTI, NVIC priorities, and DMA.
  • STM32CubeIDE: Set ISR breakpoints, run time profiler, or measure CPU load.
  • DWT Cycle Counter (if advanced timing needed):
c // Enable cycle counter CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; uint32_t start = DWT->CYCCNT; // ... do something ... uint32_t elapsed = DWT->CYCCNT - start; 
Enter fullscreen mode Exit fullscreen mode

Bonus Tips:

Image description

Summary for STM32F407 + Sensor Trigger

Image description

Top comments (0)