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
Top comments (0)