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.
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
}
}
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);
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
}
}
}
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);
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;
}
}
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
}
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;
Bonus Tips:
Summary for STM32F407 + Sensor Trigger