STM32F4数字滤波器项目中DMA失效,配置是否存在问题?
排查DMA_IRQHandler未触发的ADC+DMA+定时器配置问题
Hey there! Let's dig into why your DMA_IRQHandler isn't executing even though Timer 3 is working as expected. Since you're using Timer 3 to trigger ADC sampling at 40kHz, with DMA kicking off post-conversion, here are the key areas to validate step by step:
1. ADC Trigger & DMA Request Configuration
- Confirm ADC trigger source: Double-check that your ADC is set to use Timer 3's TRGO event as its external trigger. For most MCUs (like STM32), this means configuring the
EXTSELandEXTENbits in theADC_CR2register—make sure you've selected Timer 3's trigger output and set it to trigger on the rising edge. - Enable ADC DMA requests: Ensure the
DMAbit inADC_CR2is set to 1. This is critical: it tells the ADC to send a DMA request every time a conversion finishes. - Check conversion mode: If you're using single conversion mode, verify that the ADC restarts conversion on each Timer trigger. For continuous mode, make sure the trigger setup aligns with the continuous conversion logic.
2. DMA Channel Setup & Interrupt Enable
- Correct channel mapping: DMA channels are tied to specific peripheral requests (e.g., ADC1 on STM32F1 uses DMA1 Channel 1). Using the wrong channel means DMA will never receive the ADC's request—cross-reference your MCU's reference manual to confirm the correct channel.
- Transfer direction & data width: Set DMA to transfer from peripheral to memory (the
DIRbit inDMA_CCRx). Match the data width to your ADC's resolution (12-bit ADC = 16-bit/half-word width, for example). - Interrupt configuration:
- Enable DMA's transfer complete interrupt by setting the
TCIEbit inDMA_CCRx(or half-transfer interrupt if you're using that mode). - Don't forget to enable the DMA channel's interrupt in the NVIC! Use the appropriate function (e.g.,
NVIC_EnableIRQ(DMA1_Channel1_IRQn)for STM32) and set a reasonable priority to avoid preemption by higher-priority interrupts.
- Enable DMA's transfer complete interrupt by setting the
- Circular mode (for continuous sampling): If you're doing ongoing sampling, enable DMA's circular mode (
CIRCbit inDMA_CCRx). This resets the DMA address pointers automatically after each transfer, readying it for the next ADC conversion.
3. Code-Specific Checks
Since you mentioned a timer_init function, here are a few timer-related details to confirm:
- Timer TRGO output setup: In
TIM_CR2, set theMMSbits to configure Timer 3's TRGO output (e.g., set to "update event" if you want Timer overflow to trigger the ADC). Without this, the Timer won't send a trigger signal to the ADC at all. - ADC startup: Some MCUs require you to manually start the ADC and run calibration, even for external trigger mode. For example, call
ADC_SoftwareStartConvCmd(ADC1, ENABLE)after configuration to kick off the first conversion cycle. - Interrupt handler naming: Make sure your
DMA_IRQHandlerhas the exact name specified in your MCU's interrupt vector table. For example, STM32F1's DMA1 Channel 1 interrupt usesDMA1_Channel1_IRQHandler—a typo here means the compiler won't link the function to the interrupt, so it'll never run.
4. Debugging Tips
- Register inspection: Use your debugger to check key registers:
ADC_SR'sEOCbit: If this sets after Timer triggers, the ADC is completing conversions correctly.DMA_ISR'sTCIFxbit: If this sets but the interrupt doesn't fire, the issue is with NVIC configuration or handler naming. If it doesn't set, DMA isn't receiving the ADC's request.
- Hardware signals: Use an oscilloscope to check Timer 3's TRGO output (if accessible) or the ADC's trigger input pin—confirm the 40kHz trigger signal is actually being generated.
内容的提问来源于stack exchange,提问作者Mauricio Paulusma
相关产品推荐
相关产品推荐

