0
votes

I'm attempting to get two ADC's to simultaneously sample on a STM32H743. However, I cannot seem to read the values from ADC2 correctly. From my understanding, when running in dual simultaneous mode, the data from the two ADC conversions are written to the buffer as a 32 bit word. I have set up the STM32CubeMonitor to read the first 16 bits of the buffer and the second 16 bits and plot them. However, despite having different inputs to each adc (one square wave, and one triangle) I only see the input on ADC1. The values of ADC2 reflect what is on the input of ADC1. I'm not entirely sure what I'm doing wrong as I've tried just about every combination of settings I can think of. I would appreciate any insight.

I have tried both the NUCLEO board and the EVAL board and have not seen much success. I'm using STM32CubeIDE to configure everything and STM32CubeMonitor to monitor the values read.

Here are the configuration of both ADCs.

ADC1/ADC2

    static void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_MultiModeTypeDef multimode = {0};
  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */
  /** Common config 
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  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 = ENABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  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)
  {
    Error_Handler();
  }
  /** 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)
  {
    Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_19;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

/**
  * @brief ADC2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_ADC2_Init(void)
{

  /* USER CODE BEGIN ADC2_Init 0 */

  /* USER CODE END ADC2_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC2_Init 1 */

  /* USER CODE END ADC2_Init 1 */
  /** Common config 
  */
  hadc2.Instance = ADC2;
  hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc2.Init.Resolution = ADC_RESOLUTION_16B;
  hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc2.Init.LowPowerAutoWait = DISABLE;
  hadc2.Init.ContinuousConvMode = ENABLE;
  hadc2.Init.NbrOfConversion = 1;
  hadc2.Init.DiscontinuousConvMode = DISABLE;
  hadc2.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
  hadc2.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc2.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc2.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc2) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_18;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC2_Init 2 */

  /* USER CODE END ADC2_Init 2 */

}
1
I'm using STM32CubeIDE to configure everything HAL is the moxt probable source of the problem.0___________

1 Answers

0
votes

you need these global variables:

ALIGN_32BYTES(__IO uint32_t   ADCDualConvertedValues[4]); //array size of your adc ranks
/* dual values */
uint32_t    poz_0_dual          = 0;    //Variable holding ADC1 ADC2 values
uint32_t    poz_1_dual          = 0;    //Variable holding ADC1 ADC2 values
uint32_t    poz_2_dual          = 0;    //Variable holding ADC1 ADC2 values
uint32_t    poz_3_dual          = 0;    //Variable holding ADC1 ADC2 values

/* single VALUES */
uint16_t    poz_0_a             = 0;
uint16_t    poz_0_b             = 0;
uint16_t    poz_1_a             = 0;
uint16_t    poz_1_b             = 0;
uint16_t    poz_2_a             = 0;
uint16_t    poz_2_b             = 0;
uint16_t    poz_3_a             = 0;
uint16_t    poz_3_b             = 0;

you need to add following code to your int main(void)

if(HAL_ADC_Start(&hadc2) != HAL_OK){Error_Handler();}
if(HAL_ADCEx_MultiModeStart_DMA(&hadc1,(uint32_t *)ADCDualConvertedValues, 4)  != HAL_OK){Error_Handler();}             //Must use multimode!

In your while(1)

/* passing values */
poz_0_dual                          =   ADCDualConvertedValues[0];
poz_1_dual                          =   ADCDualConvertedValues[1];
poz_2_dual                          =   ADCDualConvertedValues[2];
poz_3_dual                          =   ADCDualConvertedValues[3];
    
/* shifting 32 to 16 */
poz_0_a                             =   (uint16_t) poz_0_dual;
poz_0_b                             =   (uint16_t) (poz_0_dual >> 16);
poz_1_a                             =   (uint16_t) poz_1_dual;
poz_1_b                             =   (uint16_t) (poz_1_dual >> 16);
poz_2_a                             =   (uint16_t) poz_2_dual;
poz_2_b                             =   (uint16_t) (poz_2_dual >> 16);
poz_3_a                             =   (uint16_t) poz_3_dual;
poz_3_b                             =   (uint16_t) (poz_3_dual >> 16);

I hope it helps to you. Don't forget multimode.DualModeData = ADC_DUALMODEDATAFORMAT_32_10_BITS; in your adc.c

mfG fejes