STM32F302单DMA通道实现ADC_DR与ADC_JDR数据分存可行性问询
Single DMA Channel for STM32F302 ADC Rule & Injection Data Transfer
Nice question! Let’s walk through how you can make this work with your STM32F302 and that single remaining DMA channel. The short answer is yes, it’s absolutely possible—you just need to combine ADC interrupts with DMA configuration tweaks to route ADC_DR and ADC_JDR data to separate memory addresses.
Here’s a step-by-step implementation plan:
1. Configure the ADC
- Group1 (Rule Group): Set it to continuous conversion mode, enable DMA requests for rule conversions (
ADC_CR2_DMA = 1), and turn on the rule conversion complete interrupt (ADC_CR1_EOCIE = 1). This keeps Group1 sampling non-stop and flags when a newADC_DRvalue is ready. - Group2 (Injection Group): Configure it to trigger on your 125kHz timer’s TRGO event, and enable the injection conversion complete interrupt (
ADC_CR1_JEOCIE = 1). We’ll handle the DMA transfer for Group2 via interrupt instead of auto-triggering, to share the single DMA channel.
2. Initialize the DMA Channel
- Set up the DMA channel for peripheral-to-memory transfers, with the initial peripheral address set to
&ADC1->DRand memory address pointing to your Group1 data buffer. - Enable circular mode (
DMA_MODE_CIRCULAR) so the DMA automatically loops back to keep capturing Group1 data without manual intervention. - Match the data width to your ADC resolution (e.g., 16-bit for 12-bit samples with alignment).
3. Handle Interrupts to Switch DMA Targets
You’ll need two interrupt handlers to manage the DMA channel’s target addresses:
- Rule Conversion Complete (EOC) Interrupt: This fires when Group1 has a new sample in
ADC_DR. Since we set up DMA in circular mode, the transfer happens automatically—you don’t need to do anything here except maybe log status if needed. - Injection Conversion Complete (JEOC) Interrupt: When Group2’s 125kHz trigger fires and a sample lands in
ADC_JDR, do this:- Disable the DMA channel temporarily (
DMA_Cmd(DMAx_Channelx, DISABLE)). - Update the DMA’s peripheral address to
&ADC1->JDR1(adjust if you’re using a different JDR register) and memory address to your Group2 data buffer. - Re-enable the DMA channel and trigger a single transfer.
- In the DMA Transfer Complete (TC) Interrupt:
- Disable the DMA channel again.
- Restore the peripheral address to
&ADC1->DRand memory address to the Group1 buffer. - Re-enable the DMA channel to resume capturing Group1 data.
- Disable the DMA channel temporarily (
Key Tips to Avoid Issues:
- Interrupt Priorities: Set the JEOC and DMA TC interrupts to a higher priority than the EOC interrupt. This ensures Group2’s time-sensitive 125kHz samples don’t get delayed by Group1’s continuous sampling.
- Keep Interrupt Handlers Lean: Avoid heavy computations in the interrupts—stick to just DMA address updates and enable/disable commands. The 125kHz rate gives you ~8µs per Group2 sample, so your handler needs to be fast enough to fit in that window.
- Validate Data Integrity: After setup, test with a known signal to make sure Group1 samples are consistent and Group2 samples aren’t dropped or corrupted.
内容的提问来源于stack exchange,提问作者WeiserM13
相关产品推荐
相关产品推荐

