Showing results for 
Search instead for 
Did you mean: 

Dual ADC mode single DMA configuration. There is no documentation on how it can be achieved(?), and no simple configuration works.


The STM32H7(4/5) documentation states that two of the ADCs on board can be used in dual ADC mode, so that their 16bit samples are read into the upper- and lower halfwords of a single 32bit register (ADCx_CDR), from where a single DMA can read them into designated buffer array.

The documentation states this in no uncertain terms:

" A single DMA request is generated each time both master and slave EOC events

have occurred. At that time, the slave ADC converted data is available in the

upper half-word of the ADCx_CDR 32-bit register and the master ADC converted

data is available in the lower half-word of ADCx_CDR register. "

There is no example, documentation, or publicly available implementation of this that I could find, and making the above happen has proven impossible to me and my colleagues. The DMA setup is straightforward, but the ADCs still read data into their respective registers, and not into a common one, or if there is a separate common register, it isn't apparent how to point the DMA there.

I'd be extremely thankful of any help, be it pointing towards examples, or working code snippets for this. Here is the ADC1 initialization segment, where I suspect the issue lies:

hadc1.Instance = ADC1;
  hadc1.Init.Resolution = ADC_RESOLUTION_16B;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = ENABLE;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T2_TRGO;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  /** Configure the ADC multi-mode
  multimode.Mode = ADC_DUALMODE_REGSIMULT;
  multimode.DualModeData = ADC_DUALMODEDATAFORMAT_32_10_BITS;
  multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_1CYCLE;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  /** Configure Regular Channel
  sConfig.Channel = ADC_CHANNEL_3;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  sConfig.SingleDiff = ADC_DIFFERENTIAL_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  sConfig.OffsetSignedSaturation = DISABLE;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

And DMA initialization seems to happen inside ADC init.

ST Employee

Hello @MHilt.1​ ,

I recommend you to follow properly the steps as described in this wiki page : Getting started with ADC - stm32mcu.

Also, you can get inspired from the available example in the STM32Cube package.


To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.


You answer is not helpful at all, and does not even address the topic in question. The page you linked describes setting up a single ADC.

I have no problems setting up a single ADC, that is trivial.

However, the page fleetingly mentions that dual modes do exist, but does not give any hints on how to use them.

I am left to assume your devices do not work as advertised.


Did you find the solution to this? I am also trying to use dual regular simultaneous mode but I couldn't find any documentation or any resource to use ADC1 and ADC2 together.


Dual mode DMA examples exist. Perhaps look at those. Compare register settings between those and your own code if that's what you are trying to achieve.


If you feel a post has answered your question, please click "Accept as Solution".